This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-10-19
Channels
- # adventofcode (1)
- # announcements (3)
- # babashka (60)
- # beginners (60)
- # calva (5)
- # clj-commons (17)
- # clj-kondo (33)
- # clj-on-windows (1)
- # clojure (40)
- # clojure-austin (3)
- # clojure-europe (19)
- # clojure-gamedev (25)
- # clojure-nl (1)
- # clojure-norway (6)
- # clojure-sweden (4)
- # clojure-uk (2)
- # clojurescript (27)
- # conjure (1)
- # core-async (1)
- # core-typed (7)
- # cursive (5)
- # datomic (35)
- # events (1)
- # fulcro (35)
- # integrant (7)
- # introduce-yourself (2)
- # kaocha (5)
- # leiningen (2)
- # lsp (26)
- # malli (13)
- # nbb (99)
- # off-topic (15)
- # pathom (12)
- # pedestal (5)
- # polylith (8)
- # portal (4)
- # rdf (19)
- # reagent (8)
- # reitit (5)
- # releases (2)
- # remote-jobs (2)
- # rewrite-clj (1)
- # shadow-cljs (94)
- # testing (2)
- # timbre (2)
- # tools-deps (16)
Using the subschemas example, I wanted to pull out some custom data from the schema structure with the associated path. From something like this… [:street {:optional true :custom-field :value} string?]
I want to make grab the path and that :value
I put in that the properties.
However, I see that using mu/subschemas does not return the properties. I guess I need to write my own walker? I find that puzzling since I think malli would need that :optional true
info.
(def Schema
(m/schema
[:map
[:purchases {:optional true } [:set string?]]]))
(mu/subschemas Schema)
When :purchases
is walked, it doesn’t list the {:optional…}there is mu/find
that works like clojure.core/find
, e.g. returns the [key properties value]
entry.
so, you can:
(def Schema
(m/schema
[:map
[:purchases {:optional true} [:set string?]]]))
(defn get-in-props [schema path]
(if-let [?entry (mu/find (mu/get-in schema (butlast path)) (last path))]
(when (vector? ?entry) (second ?entry))))
(for [sub (mu/subschemas Schema)]
(assoc sub :entry-props (get-in-props Schema (:path sub))))
;({:path [], :in [], :schema [:map [:purchases {:optional true} [:set string?]]], :entry-props nil}
; {:path [:purchases], :in [:purchases], :schema [:set string?], :entry-props {:optional true}}
; {:path [:purchases :malli.core/in], :in [:purchases :malli.core/in], :schema string?, :entry-props nil})
i don’t understand what :malli.core/in
is “about”, but this gets me what i need - thanks!
Hi 👋
I'm trying to understand 2 things about catn
:
'[:catn
[m [:schema [:ref "m"]]]
[s [:schema [:ref "s"]]]
[_ [:orn [v [:schema [:ref "v"]]] [k [:schema [:ref "k"]]]]]]
1. It seems to produce the same output whether I use :orn
or :altn
-- is there a reason to prefer one over the other?
2. The result it produces is {m {:a 1}, s #{:a}, _ [k :k]}
is there any way I can produce {m {:a 1}, s #{:a}, k :k}
instead? Where the catn
takes the name from the choice operator (`:orn`)?
Below is the full schema but you can ignore most of it, it's just the choice between vector and keyword at the end that I'm focusing on:
'[:schema
{:registry {"start" [:and vector?
[:catn
[m [:schema [:ref "m"]]]
[s [:schema [:ref "s"]]]
[_ [:orn [v [:schema [:ref "v"]]] [k [:schema [:ref "k"]]]]]]],
"m" map?,
"s" set?,
"v" [:and vector?
[:catn [a [:schema any?]] [b [:schema any?]] [c [:schema any?]]]],
"k" keyword?}}
"start"]
And an example input:
'{m {:a 1}
s #{:a}
k :k}
One thing I discovered is that I can move the name binding "inside" cat using single argument orn
instead of using catn
:
[:cat
[:orn [m [:schema [:ref "m"]]]]
[:orn [s [:schema [:ref "s"]]]]
[:altn [v [:schema [:ref "v"]]] [k [:schema [:ref "k"]]]]]
=> [[m {:a 1}] [s #{:a}] [k :k]]
Which is interesting.Why does using a schema ref catn
behave differently from an embedded catn
:
(ma/parse
'[:schema {:registry {"start" [:and vector? [:catn
[a [:schema any?]]
[b [:schema [:ref "b"]]]]],
"b" [:catn [c [:schema any?]] [d [:schema any?]]]}}
"start"],
'[1 (2 3)])
(ma/parse
'[:schema {:registry {"start" [:and vector? [:catn
[a [:schema any?]]
[b [:catn [c [:schema any?]] [d [:schema any?]]]]]]}}
"start"],
'[1 2 3])
^^ The first (using a schema ref) matches a list inside a vector [1 (2 3)]
, whereas the second (embedded) matches a flat vector [1 2 3]
-- I'm wondering if there is a way to use a ref to match a flat vector instead of a list.