Hello, I have a question about how key-transformer works.
When using key-transformer to decode a data structure, if that data structure has maps inside vectors. Should the maps inside vectors be transformed accordingly?
I have found that the transformation stops when the vector is found, however I would expect it to transform all objects of type :map recursively. Am I doing something wrong?
Example code:
look that on the roundtrip test output/result, the map inside vector is not transformed.
Looks like the encoding is doing correctly, making all keys camel case, but the decoding skips the fills vector
Could you paste code as text?
(def schema:fill
[:map
[:color :string]
[:some-id :int]])
(def schema:test-1
[:and
[:multi {:dispatch :type
:decode/string {:enter #(update % :type keyword)}}
[:group
[:map
[:type [:= :group]]
[:font-family :string]
[:font-size :int]
[:fills [:vector schema:fill]]]]]
[:fn some?]])
(def key-transformer
(sm/key-transformer {:encode json/write-camel-key
:decode json/read-kebab-key
:types #{:map :map-of :multi}}))
(def test-data
{:font-family "foobar"
:font-size 10
:type :group
:fills [{:color "#aaaaaa" :some-id 1}]})
(def encoder
(sm/encoder schema:test-1 key-transformer))
(def decoder
(sm/decoder schema:test-1 key-transformer))
(defn run-roundtrip-test
[]
(-> test-data
(encoder)
(json/encode)
(json/decode)
(decoder)))
;; The output is:
(comment
{:font-family "foobar",
:font-size 10,
:type "group",
:fills [{"color" "#aaaaaa", "someId" 1}]})(defn read-kebab-key
[k]
(-> k str/kebab keyword))
(defn write-camel-key
[k]
(if (or (keyword? k) (symbol? k))
(str/camel k)
(str k)))
The auxiliar functions based on cuerdas.core :as strWhat I find strangest is: if I remove the json/encode and json/decode from the roundtrip, it works
(just discovered that)
I think I have discovered the problem here, the problem is on the :multi decode/string It looks for :type expecting it to be decoded but in this phase the type is still a string
In any case i'm expecting key-transformer doing it's work before anything other is happens, but it is clearly that I'm wrong here
you have :decode/string in :multi , you don’t have a :string decoder in the chain
there should be a visual debugger for these 😅
yep, that fixed the issue, but it was not evident hehe
because I expect the key-transformer run before other transformers, so all keys recursivelly on the designated types transformed
yeah, but :multi doesn’t know which branch it should use. branches could be of different types, e.g. :map, :vector, :int etc.
with that assumption, Even if the string decoder does not run, i expected the case is transformed. But now I undertand that transformer uses the schema for walking the data, not the data, and with not being unable to proceed down with multi
first have to resolve the branch, then it sees the map within and runs the key-transformring
yep, I understand, thanks for your time