Compare commits
2 commits
master
...
lean-execu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bde18388d7 | ||
|
|
3f26eb1826 |
3 changed files with 103 additions and 33 deletions
|
|
@ -15,11 +15,7 @@
|
|||
"Navigates to and returns a sequence of all the elements specified by the selector."
|
||||
[selector structure]
|
||||
(let [sp (comp-paths* selector)]
|
||||
(select-full* sp
|
||||
[]
|
||||
structure
|
||||
(fn [vals structure]
|
||||
(if-not (empty? vals) [(conj vals structure)] [structure])))
|
||||
(exec-select selector structure)
|
||||
))
|
||||
|
||||
(defn select-one
|
||||
|
|
@ -51,14 +47,8 @@
|
|||
the update-fn on it"
|
||||
[selector update-fn structure]
|
||||
(let [selector (comp-paths* selector)]
|
||||
(update-full* selector
|
||||
[]
|
||||
structure
|
||||
(fn [vals structure]
|
||||
(if (empty? vals)
|
||||
(update-fn structure)
|
||||
(apply update-fn (conj vals structure)))
|
||||
))))
|
||||
(exec-update selector update-fn structure)
|
||||
))
|
||||
|
||||
(defn setval
|
||||
"Navigates to each value specified by the selector and replaces it by val"
|
||||
|
|
|
|||
|
|
@ -9,14 +9,10 @@
|
|||
(dotimes [_ iters]
|
||||
(afn))))
|
||||
|
||||
(defprotocol CoerceStructureValsPath
|
||||
(defprotocol CoercePath
|
||||
(coerce-path [this]))
|
||||
|
||||
(extend-protocol CoerceStructureValsPath
|
||||
|
||||
com.rpl.specter.protocols.StructureValsPath
|
||||
(coerce-path [this] this)
|
||||
|
||||
(extend-protocol CoercePath
|
||||
com.rpl.specter.protocols.Collector
|
||||
(coerce-path [collector]
|
||||
(reify StructureValsPath
|
||||
|
|
@ -28,21 +24,73 @@
|
|||
;; need to say Object instead of StructurePath so that things like Keyword are properly coerced
|
||||
Object
|
||||
(coerce-path [spath]
|
||||
spath))
|
||||
|
||||
(defprotocol CoerceStructureValsPath
|
||||
(coerce-structure-vals-path [this]))
|
||||
|
||||
(extend-protocol CoerceStructureValsPath
|
||||
com.rpl.specter.protocols.StructureValsPath
|
||||
(coerce-structure-vals-path [this] this)
|
||||
|
||||
com.rpl.specter.protocols.Collector
|
||||
(coerce-structure-vals-path [this] (coerce-path this))
|
||||
|
||||
|
||||
;; need to say Object instead of StructurePath so that things like Keyword are properly coerced
|
||||
Object
|
||||
(coerce-structure-vals-path [spath]
|
||||
(reify StructureValsPath
|
||||
(select-full* [this vals structure next-fn]
|
||||
(select* spath structure (fn [structure] (next-fn vals structure))))
|
||||
(update-full* [this vals structure next-fn]
|
||||
(update* spath structure (fn [structure] (next-fn vals structure)))
|
||||
)))
|
||||
)
|
||||
))))
|
||||
|
||||
(defn- combine-same-types [[f & _ :as all]]
|
||||
(cond (extends? StructureValsPath (class f))
|
||||
all
|
||||
|
||||
(extend-protocol StructureValsPathComposer
|
||||
(extends? Collector (class f))
|
||||
[(reify StructureValsPath
|
||||
(select-full* [this vals structure next-fn]
|
||||
(next-fn (reduce conj vals (for [c all] (collect-val c structure))) structure))
|
||||
(update-full* [this vals structure next-fn]
|
||||
(next-fn (reduce conj vals (for [c all] (collect-val c structure))) structure))
|
||||
)]
|
||||
|
||||
:else
|
||||
[(reduce (fn [curr sp]
|
||||
(reify StructurePath
|
||||
(select* [this structure next-fn]
|
||||
(select* sp structure
|
||||
(fn [structure-next]
|
||||
(select* curr structure-next next-fn))))
|
||||
(update* [this structure next-fn]
|
||||
(update* sp structure
|
||||
(fn [structure-next]
|
||||
(update* curr structure-next next-fn))))
|
||||
))
|
||||
(reverse all))]))
|
||||
|
||||
(defprotocol PathComposer
|
||||
(comp-paths* [paths]))
|
||||
|
||||
(extend-protocol PathComposer
|
||||
Object
|
||||
(comp-paths* [sp]
|
||||
(coerce-path sp))
|
||||
java.util.List
|
||||
(comp-paths* [structure-paths]
|
||||
(let [combined (->> structure-paths
|
||||
flatten
|
||||
(partition-by (fn [e]
|
||||
(cond (extends? StructureValsPath (class e)) :svalspath
|
||||
(extends? Collector (class e)) :collector
|
||||
:else :spath)))
|
||||
(mapcat combine-same-types))]
|
||||
(if (= 1 (count combined))
|
||||
(first combined)
|
||||
(reduce (fn [sp-curr sp]
|
||||
(reify StructureValsPath
|
||||
(select-full* [this vals structure next-fn]
|
||||
|
|
@ -55,7 +103,35 @@
|
|||
(fn [vals-next structure-next]
|
||||
(update-full* sp-curr vals-next structure-next next-fn))))
|
||||
))
|
||||
(->> structure-paths flatten (map coerce-path) reverse))
|
||||
(->> structure-paths (map coerce-structure-vals-path) reverse))
|
||||
))))
|
||||
|
||||
(defprotocol Executor
|
||||
(exec-select [selector structure])
|
||||
(exec-update [selector update-fn structure]))
|
||||
|
||||
(extend-protocol Executor
|
||||
com.rpl.specter.protocols.StructureValsPath
|
||||
(exec-select [selector structure]
|
||||
(select-full* selector
|
||||
[]
|
||||
structure
|
||||
(fn [vals structure]
|
||||
(if-not (empty? vals) [(conj vals structure)] [structure]))))
|
||||
(exec-update [selector update-fn structure]
|
||||
(update-full* selector
|
||||
[]
|
||||
structure
|
||||
(fn [vals structure]
|
||||
(if (empty? vals)
|
||||
(update-fn structure)
|
||||
(apply update-fn (conj vals structure))))))
|
||||
|
||||
Object
|
||||
(exec-select [selector structure]
|
||||
(select* selector structure (fn [e] [e])))
|
||||
(exec-update [selector update-fn structure]
|
||||
(update* selector structure update-fn)
|
||||
))
|
||||
|
||||
;; cell implementation idea taken from prismatic schema library
|
||||
|
|
@ -269,6 +345,3 @@
|
|||
(update* [this structure next-fn]
|
||||
(-> structure view-fn next-fn)
|
||||
))
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
(ns com.rpl.specter.protocols)
|
||||
|
||||
|
||||
;;TODO: might be able to speed it up more by having these return a function rather than
|
||||
;;rely on protocol methods (can then compose functions together directly)
|
||||
;;so protocol would just be used during composition - what about execution?
|
||||
;;could have a select-fast function that takes in a selector FUNCTION explicitly
|
||||
(defprotocol StructureValsPath
|
||||
(select-full* [this vals structure next-fn])
|
||||
(update-full* [this vals structure next-fn]))
|
||||
|
|
@ -12,5 +16,8 @@
|
|||
(defprotocol Collector
|
||||
(collect-val [this structure]))
|
||||
|
||||
(defprotocol StructureValsPathComposer
|
||||
(comp-paths* [paths]))
|
||||
;;TODO: Collectors in sequence become a StructureValsPath that does all collection at once
|
||||
;;StructurePath in sequence become a single StructurePath
|
||||
;;any StructureValsPath composed with anything becomes a StructureValsPath
|
||||
;;TODO: update update/select to be able to execute a StructurePath directly without coercing it
|
||||
;; - this will avoid MANY layers of indirection and overhead
|
||||
|
|
|
|||
Loading…
Reference in a new issue