Fork me on GitHub
#clojure-spec
<
2019-08-19
>
cfleming00:08:11

This seems to work:

(s/def ::entry (s/or :project (s/cat :file string? :data ::project)
                     :profiles (s/cat :key (s/and keyword? #(= (name %) "profiles"))
                                      :data (s/coll-of string? :kind vector?))))
(s/def ::projects (s/coll-of ::entry :kind map?))

cfleming00:08:26

Not pretty, but it does the trick.

cfleming00:08:29

@metametadata Thanks! I’ll try yours out since it looks like the error messages might be more helpful.

metametadata00:08:46

cool! we use an evolved version in company projects (which e.g. is more convoluted because of https://github.com/metosin/compojure-api/issues/417), but didn't have time to publish it yet

Nick14:08:01

I’m trying to write a spec for a payload wrapper map. For simplicity, the spec I’m trying to write is for a map with two keys, :query and :payload. For the purposes of this example, I’m using extremely simple examples of the payload with just maps of one key. ` (s/def ::query (and keyword? #{:avalue :anothervalue :thirdvalue})) (s/def ::email string?) (s/def ::user-id integer?) (s/def ::avalue (s/keys :req-un [::email])) (s/def ::anothervalue (s/keys :req-un [::user-id])) {:query :avalue :payload {:email “<mailto:[email protected]|[email protected]>” }} {:query :anothervalue :payload {:user-id 123}} ` I can use multi-spec and a defmulti to key off the :query object, but that doesn’t let me use the shared :payload keyword. Is the only way around this to define ::avalue and ::anothervalue in different namespaces ::avalue/payload ::anothervalue/payload? I haven’t created a lot of namespaced keywords in clojure yet.

Alex Miller (Clojure team)14:08:03

yes, you would need to use different namespaces in this case

Alex Miller (Clojure team)14:08:32

the ::query spec is redundant btw, just (s/def ::query #{:avalue :anothervalue :thirdvalue}) would be sufficient

Nick14:08:39

Do I need to create a separate valid namespace, or can I define the specs with a a namespace that doesn’t correspond to an existing clojure file? ie, does there need to be a (ns anothervalue) somewhere before I can do a (s/def ::anothervalue/payload string?)

Alex Miller (Clojure team)14:08:59

technically here, it's better to use the term "qualifier"

bellissimo 4
Alex Miller (Clojure team)14:08:08

which may correspond to an actual namespace, but doesn't have to

Alex Miller (Clojure team)14:08:46

you can use a keyword with any qualifier

Nick14:08:13

Thanks, that's quite helpful.

Alex Miller (Clojure team)14:08:06

a lot of docs in Clojure are not particularly clear on this point