Fork me on GitHub
#malli
<
2020-07-30
>
ikitommi07:07:40

as one string? Maybe something like:

(m/decode 
  [:vector {:decode/string (partial str/split ",")} int?] 
  "1,2,4,8,10"
  mt/string-transformer)
not near a computer, so not 100% sure it works

ikitommi07:07:37

first splits the string, the decodes parts string->int

danielglauser16:07:19

Thanks, I'll give that a try. I came up with this but your solution seems simpler:

(defn ids?                                                                      
  "Takes in a string and returns true if that string is of the form             
  1,4,7,9 or a sequence (in the math sense) of positive integers."              
  [data]                                                                        
  (let [ids (-> data                                                            
                (clojure.string/split #",")                                     
                (as-> ids (mapv #(Integer/parseInt %) ids)))]                   
    (every? pos? ids)))

(def GetClassesQueryOptions                                                     
  [:map                                                                        
   [:approved {:optional true} boolean?]                                        
   [:instructors {:optional true} [:fn (fn [ids] (ids? ids))]]                  
   [:machine {:optional true} [:fn (fn [ids] (ids? ids))]]                      
   [:music {:optional true} [:fn (fn [ids] (ids? ids))]]                        
   [:bookmarked {:optional true} boolean?]                                      
   [:minlength {:optional true} int?]                                           
   [:maxlength {:optional true} pos?]])

ikitommi17:07:12

It's good to keep decoding and validation in separate steps. @alexmiller has many times called the spec conform "a meat grinder", as it bundles the two and runs the transformations every time.

2