metosin / malli

High-performance data-driven data specification library for Clojure/Script.
Eclipse Public License 2.0
1.44k stars 204 forks source link

json-transformer should coerce doubles with zero fractional part to longs #986

Open irigarae opened 6 months ago

irigarae commented 6 months ago

Per the json schema specification integers also accept floating point numbers with zero fractional part:

Numbers with a zero fractional part are considered integers:

1.0
;; compliant with schema { "type": "integer" }

This breaks a bit when decoding with a json-transformer.

(m/validate :int (m/decode :int 3.0 mt/json-transformer))
#_=> false

I think it would be a nice addition to the json-decoders:

;; just an example, not taking into account clj/cljs nor NaN, etc.
(defn -float->long [x]
  (if (and (float? x) (zero? (rem x 1)))
    (long x)
    x))
(m/validate :int (m/decode :int 3.0 (mt/transformer {:decoders {:int -float->long}})))
#_=> true
;; same example
(m/decode [:int {:decode/json -float->long}] 3.0 mt/json-transformer) #_=> 3
(m/decode [:int {:decode/json -float->long}] 3.2 mt/json-transformer) #_=> 3.2
ikitommi commented 5 months ago

thanks for the info, this should be fixed.