Fork me on GitHub
#meander
<
2021-09-22
>
wilkerlucio19:09:59

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 this

ribelo20:09:42

(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}]

ribelo20:09:52

If you have any more problems, let me know. better than crossword puzzles and sudoku

2
wilkerlucio13:09:57

awesome, thank you so much, and since you asked, there is a twist on this one that I wonder if we solve strait from meander

wilkerlucio13:09:00

this is my current code:

wilkerlucio13:09:08

(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))))))

wilkerlucio13:09:30

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}]))

wilkerlucio13:09:09

so in that case, it needs to extract from [:opt :name] (sometimes its (:opt :name), so not always a vector

wilkerlucio13:09:28

and add the optional? true flag

ribelo13:09:35

to make it easier please give input and expected output

ribelo13:09:43

I don't know if I understand correctly

ribelo13:09:37

I got it, I missed something when I was reading

🆒 1
ribelo14:09:34

@U066U8JQJ

(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}} ...]
         

         {} {})))

🎉 1
ribelo14:09:51

with optional arguments, the meander is no longer concise and things get a bit messy

ribelo14:09:24

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

👍 2
ribelo14:09:04

in the worst case ?x ?x causes rewrite return unchanged whatever it takes

noprompt20:09:41

I just noticed the use of two & on the RHS. 🙂

ribelo20:09:53

I guess that's a good thing? ;>

😆 1