This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-06-05
Channels
- # babashka (14)
- # beginners (62)
- # calva (1)
- # cider (54)
- # clj-kondo (3)
- # cljdoc (15)
- # cljs-dev (2)
- # clojure (180)
- # clojure-europe (5)
- # clojure-italy (4)
- # clojure-losangeles (1)
- # clojure-nl (2)
- # clojure-spec (10)
- # clojure-uk (39)
- # clojurescript (85)
- # core-async (9)
- # core-logic (1)
- # core-typed (5)
- # data-science (27)
- # datomic (2)
- # emacs (15)
- # figwheel-main (98)
- # fulcro (26)
- # graphql (15)
- # helix (1)
- # jobs-discuss (26)
- # kaocha (1)
- # off-topic (54)
- # other-lisps (1)
- # re-frame (21)
- # reagent (1)
- # reitit (3)
- # shadow-cljs (49)
- # spacemacs (12)
- # specter (5)
- # xtdb (2)
@ikitommi Hi, a few days ago you mentioned some other libs to perform spec coercion, but I forgot to take notes on its names to check it later. Could you share the names again? Also, I'm having some trouble with coercing some data using spec-tools. I'm not sure if I got the logic right. Do you have any resource explaining how the coercion works in spec-tools? Thanks very much!
Hi @marques.goncalves.fel! The slack history (& my message) is here: https://clojurians-log.clojureverse.org/clojure-spec/2020-05-19. I believe all spec-coercion libs are doing it in the same way, : given a spec, it's form is parsed and for all different specs (`or`, and
, keys
, integer?
, any?
etc.) a transforming function is selected and applied to the value. Corcion is recursive and best effort. With spec-tools:
(require '[clojure.spec.alpha :as s])
(require '[spec-tools.core :as st])
(s/def ::spec (s/nilable
(s/nilable
(s/map-of
keyword?
(s/or :keys (s/keys :req-un [::c1])
:ks (s/coll-of (s/and int?) :into #{}))))))
(def value {"keys" {:c1 "1" ::c2 "kikka"}
"keys2" {:c1 true}
"ints" [1 "1" "invalid" "3"]})
(st/coerce ::spec value st/string-transformer)
;{:keys {:c1 "1", :test/c2 "kikka"}
; :keys2 {:c1 true}
; :ints #{1 "invalid" 3}}
(st/coerce ::spec value st/json-transformer)
;{:keys {:c1 "1", :test/c2 "kikka"}
; :keys2 {:c1 true}
; :ints #{"3" 1 "invalid" "1"}}
wrote few years back: https://www.metosin.fi/blog/spec-transformers/
Thanks for the links and explanation. Sorry for not finding the history. I looked only in slack! 😅
Learner here. Dumb Question maybe, maybe a mindset I have a map (ex JSON) in it exists the following: {:status {:timestamp "2020-04-09T15:27:00" :status "abc"} Yes, I suppose I could change the data so that the 1st :status has a different name but that is not very elegant. If the structure remains the same, I assume you cannot redefine the :status again within the spec Is there a way int spec (some technique) that deals with this type of anomaly? I have a data set exactly like that. Any thoughts?
s/keys with :req-un will match the short name of the provided spec but can use different qualified specs
(s/def :inner/status string?)
(s/def :inner/timestamp string?)
(s/def :outer/status (s/keys :req-un [:inner/status :inner/timestamp]))
(s/def :outer/map (s/keys :req-un [:outer/status]))
(s/def :inner/status string?) (s/def :inner/timestamp string?) (s/def :outer/status (s/keys :req-un [:inner/timestamp :inner/status])) (s/def :outer/map (s/keys :req-un [:inner/status])) (s/valid? :outer/map {:status {:timestamp "2020-09" :status "abc" }}) Hi, @alexmillerseems to fail against the data. Perhaps I miss it? (s/explain-str :outer/map {:status {:timestamp "2020-09" :status "abc" }}) ;; => "{:timestamp \"2020-09\", :status \"abc\"} - failed: string? in: [:status] at: [:status] spec: :inner/status\n"
@dev.4openid That works for me:
user=> (require '[clojure.spec.alpha :as s])
nil
user=> (s/def :inner/status string?)
:inner/status
user=> (s/def :inner/timestamp string?)
:inner/timestamp
user=> (s/def :outer/status (s/keys :req-un [:inner/status :inner/timestamp]))
:outer/status
user=> (s/def :outer/map (s/keys :req-un [:outer/status]))
:outer/map
(s/valid? :outer/map {:status {:timestamp "2020-09"
:status "abc" }})
true
(s/explain-str :outer/map {:status {:timestamp "2020-09"
:status "abc" }})
"Success!\n"
user=>
(you can use triple-backticks around your code to format it and make it easier to read)Hi @alexmiller and @seancorfield - thanks for the help - I am wrong: my fat fingers and compiling versions of the trial and error - I screwed up! ðŸ˜ðŸ˜€ - along day!