added cond-path and if-path selectors
This commit is contained in:
parent
6ba23bc438
commit
da2019b07b
3 changed files with 80 additions and 12 deletions
|
|
@ -11,12 +11,8 @@
|
|||
|
||||
;; Selector functions
|
||||
|
||||
(defn compiled-select
|
||||
"Version of select that takes in a selector pre-compiled with comp-paths"
|
||||
[^com.rpl.specter.impl.TransformFunctions tfns structure]
|
||||
(let [^com.rpl.specter.impl.ExecutorFunctions ex (.executors tfns)]
|
||||
((.select-executor ex) (.selector tfns) structure)
|
||||
))
|
||||
(def ^{:doc "Version of select that takes in a selector pre-compiled with comp-paths"}
|
||||
compiled-select compiled-select*)
|
||||
|
||||
(defn select
|
||||
"Navigates to and returns a sequence of all the elements specified by the selector."
|
||||
|
|
@ -63,12 +59,9 @@
|
|||
|
||||
;; Update functions
|
||||
|
||||
(defn compiled-update
|
||||
"Version of update that takes in a selector pre-compiled with comp-paths"
|
||||
[^com.rpl.specter.impl.TransformFunctions tfns update-fn structure]
|
||||
(let [^com.rpl.specter.impl.ExecutorFunctions ex (.executors tfns)]
|
||||
((.update-executor ex) (.updater tfns) update-fn structure)
|
||||
))
|
||||
|
||||
(def ^{:doc "Version of update that takes in a selector pre-compiled with comp-paths"}
|
||||
compiled-update compiled-update*)
|
||||
|
||||
(defn update
|
||||
"Navigates to each value specified by the selector and replaces it by the result of running
|
||||
|
|
@ -190,3 +183,22 @@
|
|||
(update [:a :b (putval 3)] + some-map)"
|
||||
[val]
|
||||
(->PutValCollector val))
|
||||
|
||||
(defn cond-path
|
||||
"Takes in alternating cond-fn selector cond-fn selector...
|
||||
Tests the structure on the cond-fn, and if it matches uses the following selector for
|
||||
the rest of the selector. Otherwise, it moves on to the next selector. If nothing
|
||||
matches, then the structure is not selected."
|
||||
[& conds]
|
||||
(->> conds
|
||||
(partition 2)
|
||||
(map (fn [[c p]] [c (comp-paths* p)]))
|
||||
doall
|
||||
->ConditionalPath
|
||||
))
|
||||
|
||||
(defn if-path
|
||||
"Like cond-path, but with if semantics."
|
||||
([cond-fn if-path] (cond-path cond-fn if-path))
|
||||
([cond-fn if-path else-path]
|
||||
(cond-path cond-fn if-path (fn [_] true) else-path)))
|
||||
|
|
|
|||
|
|
@ -469,3 +469,39 @@
|
|||
(update* [this structure next-fn]
|
||||
(next-fn structure)
|
||||
))
|
||||
|
||||
(defn compiled-select*
|
||||
[^com.rpl.specter.impl.TransformFunctions tfns structure]
|
||||
(let [^com.rpl.specter.impl.ExecutorFunctions ex (.executors tfns)]
|
||||
((.select-executor ex) (.selector tfns) structure)
|
||||
))
|
||||
|
||||
(defn compiled-update*
|
||||
[^com.rpl.specter.impl.TransformFunctions tfns update-fn structure]
|
||||
(let [^com.rpl.specter.impl.ExecutorFunctions ex (.executors tfns)]
|
||||
((.update-executor ex) (.updater tfns) update-fn structure)
|
||||
))
|
||||
|
||||
(deftype ConditionalPath [cond-pairs])
|
||||
|
||||
(defn- retrieve-selector [cond-pairs structure]
|
||||
(->> cond-pairs
|
||||
(drop-while (fn [[c-fn _]] (not (c-fn structure))))
|
||||
first
|
||||
second
|
||||
))
|
||||
|
||||
;;TODO: test nothing matches case
|
||||
(extend-protocol StructurePath
|
||||
ConditionalPath
|
||||
(select* [this structure next-fn]
|
||||
(if-let [selector (retrieve-selector (.cond-pairs this) structure)]
|
||||
(->> (compiled-select* selector structure)
|
||||
(mapcat next-fn)
|
||||
doall)))
|
||||
(update* [this structure next-fn]
|
||||
(if-let [selector (retrieve-selector (.cond-pairs this) structure)]
|
||||
(compiled-update* selector next-fn structure)
|
||||
structure
|
||||
)))
|
||||
|
||||
|
|
|
|||
|
|
@ -295,3 +295,23 @@
|
|||
(select [(comp-paths) k1 k2] m)
|
||||
(select [k1 (comp-paths) k2] m)
|
||||
)))
|
||||
|
||||
(deftest cond-path-test
|
||||
(is (= [4 2 6 8 10]
|
||||
(select [ALL (cond-path even? [(view inc) (view inc)]
|
||||
#(= 3 %) (view dec))]
|
||||
[1 2 3 4 5 6 7 8])))
|
||||
(is (empty? (select (if-path odd? (view inc)) 2)))
|
||||
(is (= [6 2 10 6 14]
|
||||
(update [(putval 2)
|
||||
ALL
|
||||
(if-path odd? [(view inc) (view inc)] (view dec))]
|
||||
*
|
||||
[1 2 3 4 5]
|
||||
)))
|
||||
(is (= 2
|
||||
(update [(putval 2)
|
||||
(if-path odd? (view inc))]
|
||||
*
|
||||
2)))
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue