let structurepath only execution skip all the val logic

This commit is contained in:
Nathan Marz 2015-04-27 19:04:25 -04:00
parent 277735dd9b
commit 3f26eb1826
3 changed files with 99 additions and 33 deletions

View file

@ -15,11 +15,7 @@
"Navigates to and returns a sequence of all the elements specified by the selector." "Navigates to and returns a sequence of all the elements specified by the selector."
[selector structure] [selector structure]
(let [sp (comp-paths* selector)] (let [sp (comp-paths* selector)]
(select-full* sp (exec-select selector structure)
[]
structure
(fn [vals structure]
(if-not (empty? vals) [(conj vals structure)] [structure])))
)) ))
(defn select-one (defn select-one
@ -51,14 +47,8 @@
the update-fn on it" the update-fn on it"
[selector update-fn structure] [selector update-fn structure]
(let [selector (comp-paths* selector)] (let [selector (comp-paths* selector)]
(update-full* selector (exec-update selector update-fn structure)
[] ))
structure
(fn [vals structure]
(if (empty? vals)
(update-fn structure)
(apply update-fn (conj vals structure)))
))))
(defn setval (defn setval
"Navigates to each value specified by the selector and replaces it by val" "Navigates to each value specified by the selector and replaces it by val"

View file

@ -9,14 +9,10 @@
(dotimes [_ iters] (dotimes [_ iters]
(afn)))) (afn))))
(defprotocol CoerceStructureValsPath (defprotocol CoercePath
(coerce-path [this])) (coerce-path [this]))
(extend-protocol CoerceStructureValsPath (extend-protocol CoercePath
com.rpl.specter.protocols.StructureValsPath
(coerce-path [this] this)
com.rpl.specter.protocols.Collector com.rpl.specter.protocols.Collector
(coerce-path [collector] (coerce-path [collector]
(reify StructureValsPath (reify StructureValsPath
@ -28,22 +24,74 @@
;; need to say Object instead of StructurePath so that things like Keyword are properly coerced ;; need to say Object instead of StructurePath so that things like Keyword are properly coerced
Object Object
(coerce-path [spath] (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 (reify StructureValsPath
(select-full* [this vals structure next-fn] (select-full* [this vals structure next-fn]
(select* spath structure (fn [structure] (next-fn vals structure)))) (select* spath structure (fn [structure] (next-fn vals structure))))
(update-full* [this vals structure next-fn] (update-full* [this vals structure next-fn]
(update* spath structure (fn [structure] (next-fn vals structure))) (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 Object
(comp-paths* [sp] (comp-paths* [sp]
(coerce-path sp)) (coerce-path sp))
java.util.List java.util.List
(comp-paths* [structure-paths] (comp-paths* [structure-paths]
(reduce (fn [sp-curr sp] (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 (reify StructureValsPath
(select-full* [this vals structure next-fn] (select-full* [this vals structure next-fn]
(select-full* sp vals structure (select-full* sp vals structure
@ -55,7 +103,35 @@
(fn [vals-next structure-next] (fn [vals-next structure-next]
(update-full* sp-curr vals-next structure-next next-fn)))) (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 ;; cell implementation idea taken from prismatic schema library
@ -269,6 +345,3 @@
(update* [this structure next-fn] (update* [this structure next-fn]
(-> structure view-fn next-fn) (-> structure view-fn next-fn)
)) ))

View file

@ -12,5 +12,8 @@
(defprotocol Collector (defprotocol Collector
(collect-val [this structure])) (collect-val [this structure]))
(defprotocol StructureValsPathComposer ;;TODO: Collectors in sequence become a StructureValsPath that does all collection at once
(comp-paths* [paths])) ;;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