diff --git a/src/malli/transform.cljc b/src/malli/transform.cljc index 59ae8ee5f..0bd18438a 100644 --- a/src/malli/transform.cljc +++ b/src/malli/transform.cljc @@ -6,6 +6,7 @@ #?(:clj (:import (java.time Instant ZoneId) (java.time.format DateTimeFormatter DateTimeFormatterBuilder) (java.time.temporal ChronoField) + (java.net URI) (java.util Date UUID)))) (def ^:dynamic *max-compile-depth* 10) @@ -95,6 +96,17 @@ x) x)) +#?(:clj + (defn -string->uri [x] + (if (string? x) + (try + (URI. x) + ;; TODO replace with URISyntaxException once we are on + ;; babashka >= v1.3.186. + (catch Exception _ + x)) + x))) + #?(:clj (def ^DateTimeFormatter +string->date-format+ (-> (DateTimeFormatterBuilder.) @@ -221,6 +233,7 @@ 'uuid? -string->uuid 'double? -number->double 'inst? -string->date + #?@(:clj ['uri? -string->uri]) :enum {:compile (-infer-child-compiler :decode)} := {:compile (-infer-child-compiler :decode)} @@ -231,6 +244,7 @@ :qualified-keyword -string->keyword :qualified-symbol -string->symbol :uuid -string->uuid + ;#?@(:clj [:uri -string->uri]) :set -sequential->set}) @@ -244,6 +258,7 @@ 'qualified-symbol? -any->string 'uuid? -any->string + #?@(:clj ['uri? -any->string]) :enum {:compile (-infer-child-compiler :encode)} := {:compile (-infer-child-compiler :encode)} @@ -253,7 +268,7 @@ :qualified-keyword m/-keyword->string :qualified-symbol -any->string :uuid -any->string - ;:uri any->string + ;#?@(:clj [:uri -any->string]) ;:bigdec any->string 'inst? -date->string diff --git a/test/malli/transform_test.cljc b/test/malli/transform_test.cljc index 327aec311..f5ef383d3 100644 --- a/test/malli/transform_test.cljc +++ b/test/malli/transform_test.cljc @@ -3,7 +3,8 @@ [clojure.test :refer [are deftest is testing]] [malli.core :as m] [malli.core-test] - [malli.transform :as mt])) + [malli.transform :as mt]) + #?(:clj (:import (java.net URI)))) (deftest ->interceptor-test (are [?interceptor expected] @@ -67,6 +68,11 @@ ;; Ensure that uuid0 is also a valid uuid (is (= #uuid "00000000-0000-0000-0000-000000000000" (mt/-string->uuid "00000000-0000-0000-0000-000000000000")))) +#?(:clj + (deftest string->uri + (is (= (URI. "http://example.com") (mt/-string->uri "http://example.com"))) + (is (= "broken link" (mt/-string->uri "broken link"))))) + (deftest string->date (is (= #inst "2018-04-27T18:25:37Z" (mt/-string->date "2018-04-27T18:25:37Z"))) (is (= #inst "2018-04-27T18:25:37.100Z" (mt/-string->date "2018-04-27T18:25:37.1Z"))) @@ -115,6 +121,7 @@ (deftest any->string #?(:clj (is (= "1/2" (mt/-any->string 1/2)))) + #?(:clj (is (= "http://example.com" (mt/-any->string (URI. "http://example.com"))))) (is (= "0.5" (mt/-any->string 0.5))) (is (= nil (mt/-any->string nil)))) @@ -996,7 +1003,17 @@ (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))))))) + (m/decode schema data mt/json-transformer)))))) + #?(:clj + (let [schema [:map-of uri? uri?] + good "http://example.com" + bad "invalid url" + data {good good + bad bad}] + (testing data + (is (= {(URI. good) (URI. good) + bad bad} + (m/decode schema data mt/json-transformer))))))) #?(:clj (deftest -safe-test