Closed vise890 closed 1 year ago
I'd expect malli.util/assoc-in to mirror clojure.core/assoc-in:
malli.util/assoc-in
clojure.core/assoc-in
(-> {} (assoc-in [:foo :bar] :int) (assoc-in [:foo :baz] :int)) ;; => {:foo {:bar :int, :baz :int}}
(-> [:map] ; NOTE: intermediate `:foo` map does not exist (malli.util/assoc-in [:foo :bar] :int) (malli.util/assoc-in [:foo :baz] :int) (malli.util/closed-schema)) ;; 1. Unhandled java.lang.IllegalArgumentException ;; Duplicate key: :foo ;; PersistentArrayMap.java: 73 clojure.lang.PersistentArrayMap/createWithCheck ;; core.cljc: 458 malli.core$_eager_entry_parser$_map__10301/invoke ;; core.cljc: 474 malli.core$_eager_entry_parser/invokeStatic ;; core.cljc: 453 malli.core$_eager_entry_parser/invoke ;; core.cljc: 489 malli.core$_create_entry_parser/invokeStatic ;; core.cljc: 486 malli.core$_create_entry_parser/invoke ;; core.cljc: 957 malli.core$_map_schema$reify__10614/_into_schema ;; core.cljc: 338 malli.core$_set_children/invokeStatic ;; core.cljc: 336 malli.core$_set_children/invoke ;; core.cljc: 2261 malli.core$schema_walker$fn__11256/invoke ;; core.cljc: 2048 malli.core$walk$reify__11190/_outer ;; core.cljc: 322 malli.core$_walk_entries/invokeStatic ;; core.cljc: 320 malli.core$_walk_entries/invoke ;; core.cljc: 1033 malli.core$_map_schema$reify$reify__10639/_walk ;; core.cljc: 2043 malli.core$walk/invokeStatic ;; core.cljc: 2036 malli.core$walk/invoke ;; util.cljc: 125 malli.util$closed_schema/invokeStatic ;; util.cljc: 114 malli.util$closed_schema/invoke ;; util.cljc: 123 malli.util$closed_schema/invokeStatic ;; util.cljc: 114 malli.util$closed_schema/invoke
A call to malli.core/form between the repeated assoc-in calls seems to fix the issue.
malli.core/form
assoc-in
(-> [:map] (malli.util/assoc-in [:foo :bar] :int) (malli/form) ; this seems to fix it (malli.util/assoc-in [:foo :baz] :int) (malli.util/closed-schema)) ;; => [:map {:closed true} [:foo [:map {:closed true} [:bar :int] [:baz :int]]]]
I think the problem lies in the assoc call in assoc-in, which ultimately calls -set-entries for a -map-schema
assoc
-set-entries
-map-schema
(-> [:map] (malli.util/assoc :foo [:map [:bar :int]]) (malli.util/assoc :foo [:map [:baz :int]]) (malli.util/closed-schema)) ;; 1. Unhandled java.lang.IllegalArgumentException ;; Duplicate key: :foo (-> [:map] (malli/schema) (malli/-set :foo [:map [:bar :int]]) (malli/-set :foo [:map [:baz :int]]) (malli.util/closed-schema)) ;; 1. Unhandled java.lang.IllegalArgumentException ;; Duplicate key: :foo (-> [:map] (malli.util/assoc :foo [:map [:bar :int]]) (malli.util/assoc :foo [:map [:baz :int]])) ;; => [:map [:foo [:map [:bar :int]]] [:foo [:map [:baz :int]]]] ;; ^^^^~~~~~~~~~~~~~~~~~~~~~~^^^^ NOTE duplicate key (-> [:map] (malli.util/assoc :foo [:map [:bar :int]]) (malli/form) (malli.util/assoc :foo [:map [:baz :int]])) ;; => [:map [:foo [:map [:baz :int]]]] ;; ^^^^~~~~~~~~~~~~~~~~~~~~~~~~~~ NOTE no duplicate
Oh, this is embarrassing.
fixed in [metosin/malli "0.10.3"]
[metosin/malli "0.10.3"]
Wow, that was fast! Thank you so much for the fix and the amazing library!
Expected behavior
I'd expect
malli.util/assoc-in
to mirrorclojure.core/assoc-in
:Actual behavior
Temporary fix
A call to
malli.core/form
between the repeatedassoc-in
calls seems to fix the issue.Some exploration
I think the problem lies in the
assoc
call inassoc-in
, which ultimately calls-set-entries
for a-map-schema