broken implementation of skipping protocols

This commit is contained in:
Nathan Marz 2015-05-10 02:12:06 -04:00
parent 277735dd9b
commit 47aee4d000
4 changed files with 69 additions and 28 deletions

View file

@ -4,6 +4,7 @@
:jvm-opts ["-XX:-OmitStackTraceInFastThrow"] ; this prevents JVM from doing optimizations which can remove stack traces from NPE and other exceptions
:source-paths ["src/clj"]
:test-paths ["test/clj"]
:plugins [[lein-nodisassemble "0.1.3"]]
:profiles {:dev {:dependencies
[[org.clojure/test.check "0.5.9"]]}
})

View file

@ -22,6 +22,13 @@
(if-not (empty? vals) [(conj vals structure)] [structure])))
))
(defn select-fast
[^com.rpl.specter.impl.StructureValsPathFunctions selfns structure]
((.selector selfns) [] structure
(fn [vals structure]
(if-not (empty? vals) [(conj vals structure)] [structure])))
)
(defn select-one
"Like select, but returns either one element or nil. Throws exception if multiple elements found"
[selector structure]

View file

@ -9,30 +9,54 @@
(dotimes [_ iters]
(afn))))
(defprotocol CoerceStructureValsPath
(deftype StructureValsPathFunctions [selector updater]
StructureValsPath
(select-full* [this vals structure next-fn]
(selector vals structure next-fn))
(update-full* [this vals structure next-fn]
(updater vals structure next-fn)))
(defprotocol CoerceStructureValsPathFunctions
(coerce-path [this]))
(extend-protocol CoerceStructureValsPath
(extend-protocol CoerceStructureValsPathFunctions
com.rpl.specter.protocols.StructureValsPath
(coerce-path [this] this)
(coerce-path [this]
(let [pimpl (->> this
(find-protocol-impl StructureValsPath))
selector (:select-full* pimpl)
updater (:update-full* pimpl)]
(->StructureValsPathFunctions
(fn [vals structure next-fn]
(selector this vals structure next-fn))
(fn [vals structure next-fn]
(updater this vals structure next-fn)))
))
com.rpl.specter.protocols.Collector
(coerce-path [collector]
(reify StructureValsPath
(select-full* [this vals structure next-fn]
(next-fn (conj vals (collect-val collector structure)) structure))
(update-full* [this vals structure next-fn]
(next-fn (conj vals (collect-val collector structure)) structure))))
(let [pimpl (->> collector
(find-protocol-impl Collector)
:collect-val
)
afn (fn [vals structure next-fn]
(next-fn (conj vals (pimpl collector structure)) structure)
)]
(->StructureValsPathFunctions afn afn)))
;; need to say Object instead of StructurePath so that things like Keyword are properly coerced
Object
(coerce-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)))
(coerce-path [this]
(let [pimpl (->> this
(find-protocol-impl StructurePath))
selector (:select* pimpl)
updater (:update* pimpl)]
(->StructureValsPathFunctions
(fn [vals structure next-fn]
(selector this structure (fn [structure] (next-fn vals structure))))
(fn [vals structure next-fn]
(updater this structure (fn [structure] (next-fn vals structure))))
)))
)
@ -43,18 +67,26 @@
(coerce-path sp))
java.util.List
(comp-paths* [structure-paths]
(reduce (fn [sp-curr sp]
(reify StructureValsPath
(select-full* [this vals structure next-fn]
(select-full* sp vals structure
;;TODO: don't reify any protocols... instead coerce to a "StructureValsPathFunctions" record
;; and compose functions directly
(reduce (fn [^StructureValsPathFunctions sp-curr ^StructureValsPathFunctions sp]
(let [curr-selector (.selector sp-curr)
selector (.selector sp)
curr-updater (.updater sp-curr)
updater (.updater sp)]
(->StructureValsPathFunctions
(fn [vals structure next-fn]
(selector vals structure
(fn [vals-next structure-next]
(select-full* sp-curr vals-next structure-next next-fn)))
)
(update-full* [this vals structure next-fn]
(update-full* sp vals structure
(curr-selector vals-next structure-next next-fn)
)))
(fn [vals structure next-fn]
(updater vals structure
(fn [vals-next structure-next]
(update-full* sp-curr vals-next structure-next next-fn))))
))
(curr-updater vals-next structure-next next-fn)
)))
)))
(->> structure-paths flatten (map coerce-path) reverse))
))

View file

@ -1,6 +1,7 @@
(ns com.rpl.specter.protocols)
;;TODO: can use find-protocol-impl function to avoid all the protocol calls
(defprotocol StructureValsPath
(select-full* [this vals structure next-fn])
(update-full* [this vals structure next-fn]))