Skip to content

Commit 69366e4

Browse files
authored
Merge pull request #1250 from alexander-yakushev/recursive-ref-transform
Reuse recursive ref-transformers
2 parents c37656c + a9599e3 commit 69366e4

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

src/malli/core.cljc

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2012,9 +2012,16 @@
20122012
(-parser [_] (->parser -parser))
20132013
(-unparser [_] (->parser -unparser))
20142014
(-transformer [this transformer method options]
2015-
(let [this-transformer (-value-transformer transformer this method options)
2016-
deref-transformer (-memoize (fn [] (-transformer (rf) transformer method options)))]
2017-
(-intercepting this-transformer (fn [x] (if-some [t (deref-transformer)] (t x) x)))))
2015+
(let [key [(-identify-ref-schema this) method]]
2016+
(or (some-> (get-in options [::ref-transformer-cache key]) clojure.core/deref)
2017+
(let [knot (atom nil)
2018+
this-transformer (-value-transformer transformer this method options)
2019+
deref-transformer (-memoize
2020+
(fn [] (-transformer (rf) transformer method
2021+
(assoc-in options [::ref-transformer-cache key] knot))))
2022+
f (-intercepting this-transformer (fn [x] (if-some [t (deref-transformer)] (t x) x)))]
2023+
(compare-and-set! knot nil f)
2024+
f))))
20182025
(-walk [this walker path options]
20192026
(let [accept (fn [] (-inner walker (rf) (into path [0 0])
20202027
(-update options ::walked-refs #(conj (or % #{}) ref))))]

test/malli/core_test.cljc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3681,3 +3681,19 @@
36813681
"world" [:enum "maailma"])
36823682
(is (= ["hello" "maailma"]
36833683
(mapv (comp peek m/form m/deref-all) (m/children schema)))))))
3684+
3685+
(deftest recursive-coercer-test
3686+
(let [count-into-schemas (atom 0)
3687+
reg (mr/simple-registry (assoc (m/default-schemas)
3688+
::counting (m/-proxy-schema {:type ::counting
3689+
:fn (fn [p c o]
3690+
(assert (empty? c))
3691+
(swap! count-into-schemas inc)
3692+
[[] [] (m/schema :int o)])})))
3693+
ConsCell (m/schema [:schema {:registry {::cons [:maybe [:tuple ::counting [:ref ::cons]]]}} ::cons]
3694+
{:registry reg})]
3695+
(is (= @count-into-schemas 2))
3696+
(is (m/coerce ConsCell [1 [2 [3 [4 nil]]]]))
3697+
(is (= @count-into-schemas 3)) ;; was 6
3698+
(is (m/coerce ConsCell [1 [2 [3 [4 [1 [2 [3 [4 nil]]]]]]]]))
3699+
(is (= @count-into-schemas 3)))) ;; was 10

0 commit comments

Comments
 (0)