Fork me on GitHub
#malli
<
2020-06-08
>
ikitommi06:06:18

first class :string coming up:

(m/validate :string "")
; => true

(m/validate [:string {:min 1}] "")
; => false

(json-schema/transform [:string {:min 1, :max 4}])
; => {:type "string", :minLength 1, :maxLenght 4}

(mg/sample [:string {:min 1, :max 4}])
; => ("RMmR" "5" "oL" "G7" "ENo" "cAh" "iOb" "jG" "l8" "kuo")

(-> [:map
     [:a :string]
     [:b [:string {:min 1}]]
     [:c [:string {:max 4}]]
     [:d [:string {:min 1, :max 4}]]]
    (m/explain
      {:a 123
       :b ""
       :c "invalid"
       :d ""})
    (me/humanize))
;{:a ["should be string"],
; :b ["should be at least 1 characters"],
; :c ["should be at most 4 characters"],
; :d ["should be between 1 and 4 characters"]}

馃憤 12
馃帀 7
naomarik07:06:01

Perfect. I accidentally had a string? predicate in my spec awhile ago allowing unbounded inputs.

pithyless09:06:32

@U055NJ5CC any chance for a blank? option? Or is that too specific to add to malli-core? It's the first thing I have to add to all my string specs, since you almost never want to allow user input of just blank characters. In a similar vein, do you think malli-core generator should be using char-alphanumeric or simply string? I understand the first gives you nicer looking example data, but the second is more useful in testing edge cases.

pithyless10:06:01

On second thought, the latter question is probably not worth the hassle (and one can always write a custom gen where it's needed). But still curious about a possibility of blank? or present? option.

pithyless10:06:31

I moved my question to the PR, where it is probably more appropriate.

馃憤 4
ikitommi06:06:45

@U05476190 chaned the generator to char & string.

ikitommi18:06:15

Example string-trimmer here too:

(require '[malli.transform :as mt])
(require '[malli.core :as m])
(require '[clojure.string :as str])

(defn string-trimmer []
  (mt/transformer
    {:decoders
     {:string
      {:compile (fn [schema _]
                  (let [{:string/keys [trim]} (m/properties schema)]
                    (when trim #(cond-> % (string? %) str/trim))))}}}))

(m/decode [:string {:min 1}] "    " string-trimmer)
; => "    "

(m/decode [:string {:string/trim true, :min 1}] "    " string-trimmer)
; => ""

(m/decoder :string string-trimmer)
; => #object[clojure.core$identity] ... no-op! :)