add multi-path implementation
This commit is contained in:
parent
dc1da8dfcd
commit
6a2afccbfd
3 changed files with 42 additions and 0 deletions
|
|
@ -203,3 +203,9 @@
|
|||
([cond-fn if-path] (cond-path cond-fn if-path))
|
||||
([cond-fn if-path else-path]
|
||||
(cond-path cond-fn if-path nil else-path)))
|
||||
|
||||
(defn multi-path
|
||||
"A path that branches on multiple paths. For updates,
|
||||
applies updates to the paths in order."
|
||||
[& paths]
|
||||
(->MultiPath (->> paths (map comp-paths*) doall)))
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
(defprotocol CoerceTransformFunctions
|
||||
(coerce-path [this]))
|
||||
|
||||
|
||||
(defn no-prot-error-str [obj]
|
||||
(str "Protocol implementation cannot be found for object.
|
||||
Extending Specter protocols should not be done inline in a deftype definition
|
||||
|
|
@ -519,3 +520,21 @@
|
|||
structure
|
||||
)))
|
||||
|
||||
(deftype MultiPath [paths])
|
||||
|
||||
(extend-protocol StructurePath
|
||||
MultiPath
|
||||
(select* [this structure next-fn]
|
||||
(->> (.paths this)
|
||||
(mapcat #(compiled-select* % structure))
|
||||
(mapcat next-fn)
|
||||
doall
|
||||
))
|
||||
(transform* [this structure next-fn]
|
||||
(reduce
|
||||
(fn [structure selector]
|
||||
(compiled-transform* selector next-fn structure))
|
||||
structure
|
||||
(.paths this))
|
||||
))
|
||||
|
||||
|
|
|
|||
|
|
@ -345,3 +345,20 @@
|
|||
(= (select (if-path [k1 pred] k2 k3) m)
|
||||
(select k m))
|
||||
))))
|
||||
|
||||
(defspec multi-path-test
|
||||
(for-all+
|
||||
[k1 (max-size 3 gen/keyword)
|
||||
k2 (max-size 3 gen/keyword)
|
||||
m (max-size 5
|
||||
(gen-map-with-keys
|
||||
gen/keyword
|
||||
gen/int
|
||||
k1
|
||||
k2))
|
||||
]
|
||||
(= (transform (multi-path k1 k2) inc m)
|
||||
(->> m
|
||||
(transform k1 inc)
|
||||
(transform k2 inc)))
|
||||
))
|
||||
|
|
|
|||
Loading…
Reference in a new issue