diff --git a/src/malli/transform.cljc b/src/malli/transform.cljc index 3381f0924..6fcbf5008 100644 --- a/src/malli/transform.cljc +++ b/src/malli/transform.cljc @@ -164,6 +164,14 @@ (defn -transform-map-keys [f] #(cond->> % (map? %) (into {} (map (fn [[k v]] [(f k) v]))))) +(defn -transform-if-valid [f schema] + (let [validator (m/-validator schema)] + (fn [x] + (let [out (f x)] + (if (validator out) + out + x))))) + ;; ;; sequential ;; @@ -354,9 +362,13 @@ {:name :json :decoders (-> (-json-decoders) (assoc :map-of {:compile (fn [schema _] - (or (some-> schema (m/children) (first) (m/type) map-of-key-decoders - (m/-comp m/-keyword->string) (-transform-map-keys)) - (-transform-map-keys m/-keyword->string)))}) + (let [key-schema (some-> schema (m/children) (first))] + (or (some-> key-schema (m/type) map-of-key-decoders + (-interceptor schema {}) m/-intercepting + (m/-comp m/-keyword->string) + (-transform-if-valid key-schema) + (-transform-map-keys)) + (-transform-map-keys m/-keyword->string))))}) (cond-> json-vectors (assoc :vector -sequential->vector))) :encoders (-json-encoders)}))) diff --git a/test/malli/transform_test.cljc b/test/malli/transform_test.cljc index c8f86775e..f2509ec99 100644 --- a/test/malli/transform_test.cljc +++ b/test/malli/transform_test.cljc @@ -230,6 +230,9 @@ (testing "map-of" (is (= {1 :abba, 2 :jabba} (m/decode [:map-of int? keyword?] {"1" "abba", "2" "jabba"} mt/string-transformer))) (is (= {1 :abba, 2 :jabba} (m/decode [:map-of int? keyword?] {"1" "abba", "2" "jabba"} mt/json-transformer))) + (testing "keeps original value if decoding fails" + (is (= {1 :abba, :xyz :jabba} (m/decode [:map-of int? keyword?] {"1" "abba", :xyz "jabba"} mt/json-transformer))) + (is (= {1 :abba, :xyz :jabba} (m/decode [:map-of int? keyword?] {"1" "abba", :xyz "jabba"} mt/json-transformer)))) (is (= nil (m/decode [:map-of int? keyword?] nil mt/string-transformer))) (is (= ::invalid (m/decode [:map-of int? keyword?] ::invalid mt/json-transformer)))) @@ -348,6 +351,18 @@ [:repeat {:min 2, :max 4} int?] [1 :kikka] [1 :kikka] [:repeat {:min 2, :max 4} int?] [1 2 3 4 5] [1 2 3 4 5])))) +(deftest map-of-enum-transform-test-819 + (let [schema [:map-of + [:enum {:encode/json name + :decode/json keyword} + :a :b :c] + int?] + m {:a 1 :b 2} + encoded (m/encode schema m mt/json-transformer) + decoded (m/decode schema encoded mt/json-transformer)] + (is (= {"a" 1 "b" 2} encoded)) + (is (= m decoded)))) + (deftest collection-transform-test (testing "decode" (is (= #{1 2 3} (m/decode [:set int?] [1 2 3] mt/collection-transformer))) @@ -879,11 +894,11 @@ {"0" "2ac307dc-4ec8-4046-9b7e-57716b7ecfd2" "1" "820e5003-6fff-480b-9e2b-ec3cdc5d2f78" "2" "017de28f-5801-8c62-9ce9-cef70883794a"}]] - - (is (= {0 #uuid"2ac307dc-4ec8-4046-9b7e-57716b7ecfd2" - 1 #uuid"820e5003-6fff-480b-9e2b-ec3cdc5d2f78" - 2 #uuid"017de28f-5801-8c62-9ce9-cef70883794a"} - (m/decode schema data mt/json-transformer)))))) + (testing data + (is (= {0 #uuid"2ac307dc-4ec8-4046-9b7e-57716b7ecfd2" + 1 #uuid"820e5003-6fff-480b-9e2b-ec3cdc5d2f78" + 2 #uuid"017de28f-5801-8c62-9ce9-cef70883794a"} + (m/decode schema data mt/json-transformer))))))) #?(:clj (deftest -safe-test