hello, I have another Meander puzzle 😅, this seems easier but I still hitting the wall on this:
; input data
'{:body-params {:baz int?}
:path-params {:foo string?
:bar uuid?}}
; expect output
'[{:name :baz, :kind :body-params, :type int?}
{:name :foo, :kind :path-params, :type string?}
{:name :bar, :kind :path-params, :type uuid?}]
; non-meander implementation
(defn params->fields [params]
(reduce-kv
(fn [out kind params]
(if (map? params)
(reduce-kv
(fn [out name type]
(conj out {:name name :kind kind :type type}))
out
params)
out))
[]
params))
with meander I tried using rewrites, but I ended up with some cardinal products, so wonder how you would tackle thisawesome, thank you so much, and since you asked, there is a twist on this one that I wonder if we solve strait from meander
this is my current code:
(defn params->fields [params]
(->> (m/rewrite params
{?k ?v & ?more}
[& (m/cata [?k ?v]) & (m/cata ?more)]
[?k (m/map-of !ks !vs)]
[{:kind ?k & {:name !ks :type !vs}} ...]
?x ?x)
(mapv (fn [{:keys [name] :as field}]
(cond-> field
(and (coll? name) (= :opt (first name)))
(assoc :name (second name) :optional? true))))))the mapv is to take care of optional params, here is a test including those:
(is (= (forms/params->fields
'{:path-params {:foo string?
(:opt :bar) uuid?}})
'[{:name :foo, :kind :path-params, :type string?}
{:name :bar, :kind :path-params, :type uuid?, :optional? true}]))so in that case, it needs to extract from [:opt :name] (sometimes its (:opt :name), so not always a vector
and add the optional? true flag
to make it easier please give input and expected output
I don't know if I understand correctly
I got it, I missed something when I was reading
(defn params->fields [params]
(->> (m/rewrite params
{?k ?v & ?more}
[& (m/cata [?k ?v]) & (m/cata ?more)]
[?k (m/map-of (m/or (m/and (m/keyword _ _ :as !ks) (m/let [!optional false]))
(m/and (:opt !ks) (m/let [!optional true]))) !vs)]
[{:kind ?k & {:name !ks :type !vs :optional? !optional}} ...]
{} {})))
with optional arguments, the meander is no longer concise and things get a bit messy
and in general, except quick hacking, I would advise you not to generally use the notation at the end of ?x ?x, you might get surprised. It's a good idea to throw an exception just like m/match
in the worst case ?x ?x causes rewrite return unchanged whatever it takes
I just noticed the use of two & on the RHS. 🙂
I guess that's a good thing? ;>
w8 😉
(m/rewrite '{:body-params {:baz int?}
:path-params {:foo string?
:bar uuid?}}
{?k ?v & ?more}
[& (m/cata [?k ?v]) & (m/cata ?more)]
[?k (m/map-of !ks !vs)]
[{:kind ?k & {:name !ks :type !vs}} ...]
?x ?x)
;; => [{:name :baz, :type int?, :kind :body-params}
;; {:name :foo, :type string?, :kind :path-params}
;; {:name :bar, :type uuid?, :kind :path-params}]If you have any more problems, let me know. better than crossword puzzles and sudoku