This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-09-07
Channels
- # announcements (1)
- # babashka (28)
- # beginners (212)
- # calva (13)
- # clara (3)
- # clj-kondo (39)
- # cljsrn (1)
- # clojure (16)
- # clojure-australia (1)
- # clojure-europe (11)
- # clojure-nl (2)
- # clojure-spec (9)
- # clojure-uk (8)
- # clojurescript (66)
- # cloverage (3)
- # code-reviews (16)
- # cursive (12)
- # data-science (2)
- # datomic (118)
- # events (1)
- # garden (2)
- # improve-getting-started (1)
- # introduce-yourself (1)
- # jobs (4)
- # missionary (5)
- # numerical-computing (1)
- # off-topic (5)
- # pathom (3)
- # polylith (71)
- # re-frame (99)
- # reagent (17)
- # remote-jobs (5)
- # shadow-cljs (35)
- # tools-deps (5)
- # xtdb (4)
I have read that s/keys only supports keywords. I have a large external json message for which i would to perform some top-level schema validation. Rather than performing a keywordize-keys, which may descend past the desired schema and into embedded content, I was hoping to keep the message keys as strings and use validation upon them. From what i can see, this would be done similar to this:
(def last-name? #(= "last" %))
(def first-name? #(= "first" %))
(def age? #(= "age" %))
(spec/def ::last-name (spec/tuple last-name? string?))
(spec/def ::first-name (spec/tuple first-name? string?))
(spec/def ::age (spec/tuple age? (spec/and pos-int? int?)))
(spec/def
::who
(spec/coll-of
(spec/or :last ::last-name :first ::first-name :age ::age)
:kind map?
:count 3
:distinct true))
(spec/explain ::who {"last" "smith" "first" "bob" "age" 10})
Is this the recommended path when using map keys which are strings, not keywords?This approach should work, you can simplify those preds using sets though, like #{“first”}
(and at that point I would just inline them into ::first-name
etc
You also might find it useful to wrap s/nonconforming around the s/or to simplify the conformed structure
can you provide a case where s/conform ::who json-map would return something undesirable, where s/nonconforming would be wanted?
(spec/or :last ::last-name :first ::first-name :age ::age)
is going to conform to [:last ["last" "smith"]]
(spec/nonconforming (spec/or :last ::last-name :first ::first-name :age ::age))
will conform to ["last" "smith"]
if you use :into {}
in your ::who spec, you can actually conform back to the original map if you want that
great to know. appreciated
didn't need the :into. wrapping the s/or in a nonconforming was enough to return a map when calling conform