|
3 | 3 | [malli.core :as m]
|
4 | 4 | [malli.util :as mu]))
|
5 | 5 |
|
| 6 | +(declare default-errors error-message) |
| 7 | + |
6 | 8 | (defn -pr-str [v] #?(:clj (pr-str v), :cljs (str v)))
|
7 | 9 |
|
8 | 10 | (defn -pred-min-max-error-fn [{:keys [pred message]}]
|
9 |
| - (fn [{:keys [schema value]} _] |
| 11 | + (fn [{:keys [schema value negated]} _] |
10 | 12 | (let [{:keys [min max]} (m/properties schema)]
|
11 | 13 | (cond
|
12 | 14 | (not (pred value)) message
|
13 | 15 | (and min (= min max)) (str "should be " min)
|
14 |
| - (and min (< value min)) (str "should be at least " min) |
15 |
| - max (str "should be at most " max))))) |
| 16 | + (and min ((if negated >= <) value min)) (str "should be at least " min) |
| 17 | + max (str "should be at most " max) |
| 18 | + negated message)))) |
| 19 | + |
| 20 | +(let [prefix (str "-en-humanize-negation-" (random-uuid))] |
| 21 | + (defn- -en-humanize-negation [{:keys [schema negated] :as error} options] |
| 22 | + (if negated |
| 23 | + (negated (error-message (dissoc error :negated) options)) |
| 24 | + (let [remove-prefix #(str/replace-first % prefix "") |
| 25 | + negated? #(str/starts-with? % prefix)] |
| 26 | + (loop [schema schema] |
| 27 | + (or (when-some [s (error-message (assoc error :negated #(some->> % (str prefix))) options)] |
| 28 | + (if (negated? s) |
| 29 | + (remove-prefix s) |
| 30 | + (or (when (and (string? s) |
| 31 | + (str/starts-with? s "should not ")) |
| 32 | + (str/replace-first s "should not" "should")) |
| 33 | + (when (and (string? s) |
| 34 | + (str/starts-with? s "should ")) |
| 35 | + (str/replace-first s "should" "should not"))))) |
| 36 | + (let [dschema (m/deref schema)] |
| 37 | + (when-not (identical? schema dschema) |
| 38 | + (recur dschema))))))))) |
| 39 | + |
| 40 | +(defn- -forward-negation [?schema {:keys [negated] :as error} options] |
| 41 | + (let [schema (m/schema ?schema options)] |
| 42 | + (negated (error-message (-> error (dissoc :negated) (assoc :schema schema)) options)))) |
16 | 43 |
|
17 | 44 | (def default-errors
|
18 | 45 | {::unknown {:error/message {:en "unknown error"}}
|
|
64 | 91 | 'uri? {:error/message {:en "should be a uri"}}
|
65 | 92 | #?@(:clj ['decimal? {:error/message {:en "should be a decimal"}}])
|
66 | 93 | 'inst? {:error/message {:en "should be an inst"}}
|
67 |
| - 'seqable? {:error/message {:en "should be a seqable"}} |
68 |
| - 'indexed? {:error/message {:en "should be an indexed"}} |
| 94 | + 'seqable? {:error/message {:en "should be seqable"}} |
| 95 | + 'indexed? {:error/message {:en "should be indexed"}} |
69 | 96 | 'map? {:error/message {:en "should be a map"}}
|
70 | 97 | 'vector? {:error/message {:en "should be a vector"}}
|
71 | 98 | 'list? {:error/message {:en "should be a list"}}
|
|
79 | 106 | #?@(:clj ['rational? {:error/message {:en "should be a rational"}}])
|
80 | 107 | 'coll? {:error/message {:en "should be a coll"}}
|
81 | 108 | 'empty? {:error/message {:en "should be empty"}}
|
82 |
| - 'associative? {:error/message {:en "should be an associative"}} |
83 |
| - 'sequential? {:error/message {:en "should be a sequential"}} |
| 109 | + 'associative? {:error/message {:en "should be associative"}} |
| 110 | + 'sequential? {:error/message {:en "should be sequential"}} |
84 | 111 | #?@(:clj ['ratio? {:error/message {:en "should be a ratio"}}])
|
85 | 112 | #?@(:clj ['bytes? {:error/message {:en "should be bytes"}}])
|
86 | 113 | :re {:error/message {:en "should match regex"}}
|
87 |
| - :=> {:error/message {:en "invalid function"}} |
| 114 | + :=> {:error/message {:en "should be a valid function"}} |
88 | 115 | 'ifn? {:error/message {:en "should be an ifn"}}
|
89 |
| - 'fn? {:error/message {:en "should be an fn"}} |
| 116 | + 'fn? {:error/message {:en "should be a fn"}} |
90 | 117 | :enum {:error/fn {:en (fn [{:keys [schema]} _]
|
91 | 118 | (str "should be "
|
92 | 119 | (if (= 1 (count (m/children schema)))
|
93 | 120 | (-pr-str (first (m/children schema)))
|
94 | 121 | (str "either " (->> (m/children schema) butlast (map -pr-str) (str/join ", "))
|
95 | 122 | " or " (-pr-str (last (m/children schema)))))))}}
|
| 123 | + :not {:error/fn {:en (fn [{:keys [schema] :as error} options] |
| 124 | + (-en-humanize-negation (assoc error :schema (-> schema m/children first)) options))}} |
96 | 125 | :any {:error/message {:en "should be any"}}
|
97 | 126 | :nil {:error/message {:en "should be nil"}}
|
98 |
| - :string {:error/fn {:en (fn [{:keys [schema value]} _] |
| 127 | + :string {:error/fn {:en (fn [{:keys [schema value negated]} _] |
99 | 128 | (let [{:keys [min max]} (m/properties schema)]
|
100 | 129 | (cond
|
101 | 130 | (not (string? value)) "should be a string"
|
102 | 131 | (and min (= min max)) (str "should be " min " character" (when (not= 1 min) "s"))
|
103 |
| - (and min (< (count value) min)) (str "should be at least " min " character" |
104 |
| - (when (not= 1 min) "s")) |
105 |
| - max (str "should be at most " max " character" (when (not= 1 max) "s")))))}} |
| 132 | + (and min ((if negated >= <) (count value) min)) (str "should be at least " min " character" |
| 133 | + (when (not= 1 min) "s")) |
| 134 | + max (str "should be at most " max " character" (when (not= 1 max) "s")) |
| 135 | + negated "should be a string")))}} |
106 | 136 | :int {:error/fn {:en (-pred-min-max-error-fn {:pred int?, :message "should be an integer"})}}
|
107 | 137 | :double {:error/fn {:en (-pred-min-max-error-fn {:pred double?, :message "should be a double"})}}
|
108 | 138 | :boolean {:error/message {:en "should be a boolean"}}
|
|
111 | 141 | :qualified-keyword {:error/message {:en "should be a qualified keyword"}}
|
112 | 142 | :qualified-symbol {:error/message {:en "should be a qualified symbol"}}
|
113 | 143 | :uuid {:error/message {:en "should be a uuid"}}
|
114 |
| - :> {:error/fn {:en (fn [{:keys [schema value]} _] |
115 |
| - (if (number? value) |
116 |
| - (str "should be larger than " (first (m/children schema))) |
117 |
| - "should be a number"))}} |
118 |
| - :>= {:error/fn {:en (fn [{:keys [schema value]} _] |
119 |
| - (if (number? value) |
120 |
| - (str "should be at least " (first (m/children schema))) |
121 |
| - "should be a number"))}} |
122 |
| - :< {:error/fn {:en (fn [{:keys [schema value]} _] |
123 |
| - (if (number? value) |
124 |
| - (str "should be smaller than " (first (m/children schema))) |
125 |
| - "should be a number"))}} |
126 |
| - :<= {:error/fn {:en (fn [{:keys [schema value]} _] |
127 |
| - (if (number? value) |
128 |
| - (str "should be at most " (first (m/children schema))) |
129 |
| - "should be a number"))}} |
| 144 | + :> {:error/fn {:en (fn [{:keys [schema value negated] :as error} options] |
| 145 | + (if negated |
| 146 | + (-forward-negation [:<= (first (m/children schema))] error options) |
| 147 | + (if (number? value) |
| 148 | + (str "should be larger than " (first (m/children schema))) |
| 149 | + "should be a number")))}} |
| 150 | + :>= {:error/fn {:en (fn [{:keys [schema value negated] :as error} options] |
| 151 | + (if negated |
| 152 | + (-forward-negation [:< (first (m/children schema))] error options) |
| 153 | + (if (number? value) |
| 154 | + (str "should be at least " (first (m/children schema))) |
| 155 | + "should be a number")))}} |
| 156 | + :< {:error/fn {:en (fn [{:keys [schema value negated] :as error} options] |
| 157 | + (if negated |
| 158 | + (-forward-negation [:>= (first (m/children schema))] error options) |
| 159 | + (if (number? value) |
| 160 | + (str "should be smaller than " (first (m/children schema))) |
| 161 | + "should be a number")))}} |
| 162 | + :<= {:error/fn {:en (fn [{:keys [schema value negated] :as error} options] |
| 163 | + (if negated |
| 164 | + (-forward-negation [:> (first (m/children schema))] error options) |
| 165 | + (if (number? value) |
| 166 | + (str "should be at most " (first (m/children schema))) |
| 167 | + "should be a number")))}} |
130 | 168 | := {:error/fn {:en (fn [{:keys [schema]} _]
|
131 | 169 | (str "should be " (-pr-str (first (m/children schema)))))}}
|
132 | 170 | :not= {:error/fn {:en (fn [{:keys [schema]} _]
|
|
0 commit comments