malli
malli copied to clipboard
Json decoder doesn't convert :map key strings to keywords
(m/decode [:map [:user-id :string]] {"user-id" "foo"} mt/json-transformer)
;; => {"user-id" "foo"}
(m/decode [:map-of :keyword :string] {"user-id" "foo"} mt/json-transformer)
;; => {:user-id "foo"}
I think the first one should work, similar to :map-of
. I guess Malli is just missing :map
decoder which is aware of map keys?
Thank you for opening the issue @Deraen Could you point to the code that needs to be fixed. Take into consideration that it's my first look into Malli code base.
Simplified json-transformer with :map
decoder. But this has performance considerations because this will run for every :map
schema in the value being decoded:
(defn json-transformer
([] (json-transformer nil))
([{::keys [json-vectors]}]
(mt/transformer
{:name :json
:decoders (-> (mt/-json-decoders)
;; Missing :map-of from existing json-transformer
(assoc :map {:compile (fn [schema _]
(fn [value]
(reduce (fn [v k]
(if (contains? v k)
v
;; If map contains value for the key but with key as string,
;; replace the name.
(if-let [x (get v (name k))]
(-> v
(assoc k x)
(dissoc (name k)))
v)))
value
;; List of :map keys
(map first (m/entries schema)))))})
(cond-> json-vectors (assoc :vector mt/-sequential->vector)))
:encoders (mt/-json-encoders)})))
TODO: Namespaced keys and other possible corner cases with keywords.
https://github.com/metosin/malli/blob/master/src/malli/transform.cljc#L339-L351 Will need to implement something similar (but hopefully more performant.)