This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-01-07
Channels
- # adventofcode (3)
- # announcements (6)
- # babashka (20)
- # beginners (53)
- # calva (11)
- # clj-kondo (11)
- # clojure (50)
- # clojure-argentina (4)
- # clojure-dev (1)
- # clojure-europe (14)
- # clojure-houston (1)
- # clojure-italy (2)
- # clojure-nl (4)
- # clojure-norway (3)
- # clojure-seattle (3)
- # clojure-uk (13)
- # clojurescript (2)
- # cloverage (1)
- # code-reviews (4)
- # conjure (2)
- # cursive (5)
- # datalevin (4)
- # datascript (33)
- # datomic (16)
- # events (1)
- # graphql (10)
- # gratitude (1)
- # honeysql (6)
- # introduce-yourself (2)
- # jobs (1)
- # lsp (88)
- # malli (8)
- # off-topic (3)
- # other-languages (4)
- # polylith (3)
- # re-frame (16)
- # reagent (17)
- # reitit (3)
- # releases (2)
- # remote-jobs (1)
- # rewrite-clj (3)
- # shadow-cljs (3)
- # slack-help (2)
- # sql (36)
- # testing (31)
- # tools-deps (41)
- # xtdb (23)
Trying to understand why transformers won't compose, in this ex, (mt/transformers {:decoders ...})
is compiled but not run when the second transformer (mt/key-transformer ...) is present.
If I remove (mt/key-transformer ...)
then (mt/transformers {:decoders ...})
run just fine.
I'm guessing this is related to interceptor :before and :after clashing for some reason.
(ma/decode
[:map ["ContactMethodCde"
[:enum {:lkp {"pcme" "Email"
"pcmp" "Phone"
"pcmm" "Mail"}}
"Mail" "Phone" "Email"]]]
{"ContactMethodCde" "pcme"}
(mt/transformer
{:decoders {:enum {:compile (fn [schema _]
(let [m (:lkp (ma/properties schema))]
(fn [x]
(prn x)
(m x))))}}}
(mt/key-transformer
{:decode {"ContactMethodCde" :contact-method}})))
This work, notice the :leave interceptor on :map decoders.
(ma/decode
[:map ["ContactMethodCde"
[:enum {:lkp {"pcme" "Email"
"pcmp" "Phone"
"pcmm" "Mail"}}
"Mail" "Phone" "Email"]]]
{"ContactMethodCde" "pcme"}
(mt/transformer
{:decoders
{:enum {:compile (fn [schema _]
(let [m (:lkp (ma/properties schema))]
{:enter(fn [x]
(prn x)
(m x))}))}
:map {:leave (mt/-transform-map-keys {"ContactMethodCde" :contact-method})}}}))
It wont work when the decoder is set to :enter :map {:enter ...}
Is there an equivalent to spec-alpha2's select
in malli? i.e., it takes a :map
schema and makes everything optional other than the specified keys?
something like this?
(require '[malli.core :as m])
(require '[malli.util :as mu])
(defn select [schema keys]
(-> schema
(mu/optional-keys)
(mu/required-keys keys)))
(select
[:schema {:registry {::name :string
::title [:enum "boss" "not-boss"]
::age :int
::skills [:set [:enum "clj" "cljs"]]}}
[:map ::name ::title ::age ::skills]]
#{::name ::age})
;[:map
; [:user/name :user/name]
; [:user/title {:optional true} :user/title]
; [:user/age :user/age]
; [:user/skills {:optional true} :user/skills]]
should be easy to make it recursive, I think there is an issue to add such a tool to malli.util
…
@U055NJ5CC that's definitely simpler than my solution… thanks!
what about this?
(defn select
[schema ks]
(let [schema (m/schema schema)
plain-keys (filter keyword? ks)
map-keys (->> ks
(filter map?)
(apply merge)
(not-empty))
req-keys (vec (concat plain-keys (keys map-keys)))
changed-schema (-> (mu/optional-keys schema)
(mu/required-keys req-keys))]
(if-let [paths map-keys]
(reduce (fn [schema [path v]]
(assert (vector? v) "Nested map vals must be vectors")
(mu/update schema path select v))
changed-schema
paths)
changed-schema)))
works like this:
(select
(m/schema
[:map
[:name string?]
[:title [:enum "boss" "not-boss"]]
[:skills [:set [:enum "clj" "cljs"]]]
[:base [:map
[:this-one [:map
[:one uuid?]
[:two int?]]]
[:not-this-one string?]]]])
[:name {:base [{:this-one [:two]}]}])
; [:map
; [:name string?]
; [:title {:optional true} [:enum "boss" "not-boss"]]
; [:skills {:optional true} [:set [:enum "clj" "cljs"]]]
; [:base [:map
; [:this-one [:map
; [:one {:optional true} uuid?]
; [:two int?]]]
; [:not-this-one {:optional true} string?]]]]
something like this?
(require '[malli.core :as m])
(require '[malli.util :as mu])
(defn select [schema keys]
(-> schema
(mu/optional-keys)
(mu/required-keys keys)))
(select
[:schema {:registry {::name :string
::title [:enum "boss" "not-boss"]
::age :int
::skills [:set [:enum "clj" "cljs"]]}}
[:map ::name ::title ::age ::skills]]
#{::name ::age})
;[:map
; [:user/name :user/name]
; [:user/title {:optional true} :user/title]
; [:user/age :user/age]
; [:user/skills {:optional true} :user/skills]]
what about this?
(defn select
[schema ks]
(let [schema (m/schema schema)
plain-keys (filter keyword? ks)
map-keys (->> ks
(filter map?)
(apply merge)
(not-empty))
req-keys (vec (concat plain-keys (keys map-keys)))
changed-schema (-> (mu/optional-keys schema)
(mu/required-keys req-keys))]
(if-let [paths map-keys]
(reduce (fn [schema [path v]]
(assert (vector? v) "Nested map vals must be vectors")
(mu/update schema path select v))
changed-schema
paths)
changed-schema)))