This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-03-17
Channels
- # announcements (7)
- # babashka (56)
- # beginners (114)
- # bristol-clojurians (4)
- # calva (22)
- # cider (7)
- # clara (1)
- # clj-kondo (17)
- # cljs-dev (1)
- # clojure (93)
- # clojure-europe (8)
- # clojure-italy (5)
- # clojure-nl (2)
- # clojure-uk (79)
- # clojuredesign-podcast (18)
- # clojurescript (108)
- # code-reviews (6)
- # cursive (3)
- # data-science (16)
- # datomic (151)
- # duct (7)
- # emacs (10)
- # events (1)
- # fulcro (76)
- # luminus (8)
- # off-topic (3)
- # other-lisps (2)
- # pathom (8)
- # re-frame (5)
- # reitit (8)
- # schema (9)
- # shadow-cljs (37)
- # specter (3)
- # sql (17)
- # tree-sitter (2)
- # yada (9)
I'm struggling somewhat to understand how to set up a custom coercion in schema.
I want a schema and coercion that wants to accept a string "2020-03-18"
and coerces it to a LocalDate
we do that at the json layer with 'cheshire.generate/add-encoder'
err sorry that's for serialization, you want coercion
we use 'ring.swagger.coerce/coerce'
(defmethod coerce/time-matcher LocalDate
[_]
#(if (jt/local-date? %)
%
(try
(jt/local-date local-date-format %)
(catch Exception original-exc
(let [result (try-parse-as-date %)]
(if (nil? result)
(throw original-exc)
result))))))
@braden.shepherdson just opened a old project which uses Schema + Joda, mapping look like this:
;;
;; joda-time
;;
(defn ->DateTime [date] (if (instance? Date date) (tc/from-date date) date))
(defn parse-date-time ^DateTime [date] (tf/parse (tf/formatters :date-time-parser) (->DateTime date)))
(defn parse-date ^DateTime [date] (tf/parse-local-date (tf/formatters :date) (->DateTime date)))
(defn parse-time ^DateTime [date] (tf/parse-local-time (tf/formatters :time-parser) (->DateTime date)))
(defmethod schema-tools.swagger.core/transform-type DateTime [_ _] {:type "string" :format "date-time"})
(defmethod schema-tools.swagger.core/transform-type LocalDate [_ _] {:type "string" :format "date"})
(defmethod schema-tools.swagger.core/transform-type LocalTime [_ _] {:type "string" :format "time"})
;;
;; helpers
;;
(defn cond-matcher [preds]
(fn [x]
(or
(some
(fn [[f1 f2]]
(if (f1 x) (f2 x)))
preds)
x)))
(def keyword->int
{s/Int (cond-matcher
{string? stc/string->long
number? sc/safe-long-cast
keyword? (fn [x]
(try
(Long/valueOf (name x))
(catch Exception _ x)))})})
(def keyword->string
{String (cond-matcher {keyword? name})})
(def string->joda
{DateTime (cond-matcher {string? parse-date-time})
LocalDate (cond-matcher {string? parse-date})
LocalTime (cond-matcher {string? parse-time})})
(def json-coercion-matcher
(some-fn keyword->int keyword->string string->joda stc/json-coercion-matcher))
(def string-coercion-matcher
(some-fn keyword->int keyword->string string->joda stc/string-coercion-matcher))
another example of custom coercion - what about forcing things to uppercase or lowercase?
I'm not super concerned about that since this is an API intended to be target by my own code, but still.