This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-09-26
Channels
- # announcements (1)
- # babashka (106)
- # beginners (11)
- # biff (7)
- # calva (16)
- # clj-kondo (40)
- # clj-on-windows (5)
- # clj-yaml (10)
- # clojars (4)
- # clojure (37)
- # clojure-austin (22)
- # clojure-australia (1)
- # clojure-europe (40)
- # clojure-nl (1)
- # clojure-norway (10)
- # clojure-spec (6)
- # clojure-uk (6)
- # clojurescript (13)
- # conjure (11)
- # cursive (14)
- # datalevin (8)
- # datascript (5)
- # emacs (39)
- # events (1)
- # fulcro (55)
- # gratitude (4)
- # holy-lambda (2)
- # humbleui (9)
- # instaparse (1)
- # lsp (3)
- # malli (12)
- # meander (2)
- # membrane (7)
- # nbb (1)
- # off-topic (16)
- # pathom (9)
- # releases (3)
- # sci (14)
- # shadow-cljs (25)
Is there a way to describe that a map should contain either one specific key or another key? e.g.
{:foo 1} ; correct
{:bar 1} ; correct
{} ; incorrect, should contain one of :foo or :bar
[:or [:map [:foo [:= 1]]] [:map [:bar [:= 1]]]]
yep thanks, 🙂 but there are many more keys in the map so that would be loads of duplication, maybe there’s a way to do ir inside the map
e.g.,
user=> (m/validate [:map [:or [:foo :int]] [:bar :int]] {:quz 1})
Execution error (ExceptionInfo) at malli.core/-fail! (core.cljc:138).
:malli.core/invalid-schema {:schema :x}
You could use a :fn schema for that purpose : It is naive but it works
(def FooOrBar
[:and
[:map
[:foo {:optional true} number?]
[:bar {:optional true} number?]]
[:fn
{:error/message "Only one key must be present"}
(fn [data]
(= 1 (count data)))]])
(m/validate FooOrBar {:foo 1}) => true
(m/validate FooOrBar {:bar 1}) => true
(m/validate FooOrBar {:foo 1 :bar 1}) => false
(m/validate FooOrBar {}) => false
> but there are many more keys in the map so that would be loads of duplication
The duplication can be resolved via composition, ala :merge
, :union
or even :select-keys
.
Remember also, that you may need to close the map schemas appropriately, if you do not want both :foo and :bar to be valid together.
I would prefer :or
over :and
, since it is more likely to be generator friendly; but you may even consider a version using :multi
with custom dispatcher that checks for the existence of certain keys.
I have similar case, and I tried :and
and :or
and closing all maps. It doesn't work, because one of the specs won't pass the keys missing in another maps.
https://twitter.com/RobStuttaford/status/1574430197079752706 (is it ok for me to paste a link to a tweet like this?)
This is very nice, I wonder if we could do the same with cider...it would be very cool to be able to customize the jump to reference functionality
I am trying to get swagger-ui to work in reitit but am failing. I just want to double check if reitit + swagger-ui works when malli is used to spec the routes. The docs at https://github.com/metosin/reitit/blob/master/doc/ring/swagger.md say that "Reitit supports https://swagger.io/ documentation, thanks to https://github.com/metosin/schema-tools and https://github.com/metosin/spec-tools., i.e. malli is not mentioned.
I can confirm that swagger works with malli if reitit.coercion.malli/coercion
is used.