clean up terminology – defpath -> defnav, path -> nav, fixed-pathed-path -> fixed-pathed-nav, variable-pathed-path -> variable-pathed-nav, StructurePath -> Navigator (breaking changes)
This commit is contained in:
parent
c567045fb5
commit
cdcdbbbaa4
6 changed files with 92 additions and 93 deletions
|
|
@ -3,20 +3,20 @@
|
||||||
[com.rpl.specter.macros
|
[com.rpl.specter.macros
|
||||||
:refer
|
:refer
|
||||||
[pathed-collector
|
[pathed-collector
|
||||||
variable-pathed-path
|
variable-pathed-nav
|
||||||
fixed-pathed-path
|
fixed-pathed-nav
|
||||||
defcollector
|
defcollector
|
||||||
defpath
|
defnav
|
||||||
defpathedfn
|
defpathedfn
|
||||||
]]
|
]]
|
||||||
)
|
)
|
||||||
(:use [com.rpl.specter.protocols :only [StructurePath]]
|
(:use [com.rpl.specter.protocols :only [Navigator]]
|
||||||
#+clj [com.rpl.specter.macros :only
|
#+clj [com.rpl.specter.macros :only
|
||||||
[pathed-collector
|
[pathed-collector
|
||||||
variable-pathed-path
|
variable-pathed-nav
|
||||||
fixed-pathed-path
|
fixed-pathed-nav
|
||||||
defcollector
|
defcollector
|
||||||
defpath
|
defnav
|
||||||
defpathedfn]]
|
defpathedfn]]
|
||||||
)
|
)
|
||||||
(:require [com.rpl.specter.impl :as i]
|
(:require [com.rpl.specter.impl :as i]
|
||||||
|
|
@ -119,7 +119,7 @@
|
||||||
|
|
||||||
(defn replace-in
|
(defn replace-in
|
||||||
"Similar to transform, except returns a pair of [transformed-structure sequence-of-user-ret].
|
"Similar to transform, except returns a pair of [transformed-structure sequence-of-user-ret].
|
||||||
The transform-fn in this case is expected to return [ret user-ret]. ret is
|
The transform-fn in this case is expected to return [ret user-ret]. ret is
|
||||||
what's used to transform the data structure, while user-ret will be added to the user-ret sequence
|
what's used to transform the data structure, while user-ret will be added to the user-ret sequence
|
||||||
in the final return. replace-in is useful for situations where you need to know the specific values
|
in the final return. replace-in is useful for situations where you need to know the specific values
|
||||||
of what was transformed in the data structure."
|
of what was transformed in the data structure."
|
||||||
|
|
@ -151,7 +151,7 @@
|
||||||
|
|
||||||
;; Built-in pathing and context operations
|
;; Built-in pathing and context operations
|
||||||
|
|
||||||
(defpath
|
(defnav
|
||||||
^{:doc "Stops navigation at this point. For selection returns nothing and for
|
^{:doc "Stops navigation at this point. For selection returns nothing and for
|
||||||
transformation returns the structure unchanged"}
|
transformation returns the structure unchanged"}
|
||||||
STOP
|
STOP
|
||||||
|
|
@ -162,7 +162,7 @@
|
||||||
structure
|
structure
|
||||||
))
|
))
|
||||||
|
|
||||||
(defpath
|
(defnav
|
||||||
^{:doc "Stays navigated at the current point. Essentially a no-op navigator."}
|
^{:doc "Stays navigated at the current point. Essentially a no-op navigator."}
|
||||||
STAY
|
STAY
|
||||||
[]
|
[]
|
||||||
|
|
@ -171,15 +171,15 @@
|
||||||
(transform* [this structure next-fn]
|
(transform* [this structure next-fn]
|
||||||
(next-fn structure)))
|
(next-fn structure)))
|
||||||
|
|
||||||
(def ALL (comp-paths (i/->AllStructurePath)))
|
(def ALL (comp-paths (i/->AllNavigator)))
|
||||||
|
|
||||||
(def VAL (i/->ValCollect))
|
(def VAL (i/->ValCollect))
|
||||||
|
|
||||||
(def LAST (comp-paths (i/->PosStructurePath last i/set-last)))
|
(def LAST (comp-paths (i/->PosNavigator last i/set-last)))
|
||||||
|
|
||||||
(def FIRST (comp-paths (i/->PosStructurePath first i/set-first)))
|
(def FIRST (comp-paths (i/->PosNavigator first i/set-first)))
|
||||||
|
|
||||||
(defpath
|
(defnav
|
||||||
^{:doc "Uses start-fn and end-fn to determine the bounds of the subsequence
|
^{:doc "Uses start-fn and end-fn to determine the bounds of the subsequence
|
||||||
to select when navigating. Each function takes in the structure as input."}
|
to select when navigating. Each function takes in the structure as input."}
|
||||||
srange-dynamic
|
srange-dynamic
|
||||||
|
|
@ -190,7 +190,7 @@
|
||||||
(i/srange-transform structure (start-fn structure) (end-fn structure) next-fn)
|
(i/srange-transform structure (start-fn structure) (end-fn structure) next-fn)
|
||||||
))
|
))
|
||||||
|
|
||||||
(defpath
|
(defnav
|
||||||
^{:doc "Navigates to the subsequence bound by the indexes start (inclusive)
|
^{:doc "Navigates to the subsequence bound by the indexes start (inclusive)
|
||||||
and end (exclusive)"}
|
and end (exclusive)"}
|
||||||
srange
|
srange
|
||||||
|
|
@ -205,7 +205,7 @@
|
||||||
|
|
||||||
(def END (srange-dynamic count count))
|
(def END (srange-dynamic count count))
|
||||||
|
|
||||||
(defpath
|
(defnav
|
||||||
^{:doc "Navigates to the specified subset (by taking an intersection).
|
^{:doc "Navigates to the specified subset (by taking an intersection).
|
||||||
In a transform, that subset in the original set is changed to the
|
In a transform, that subset in the original set is changed to the
|
||||||
new value of the subset."}
|
new value of the subset."}
|
||||||
|
|
@ -221,7 +221,7 @@
|
||||||
(set/union newset))
|
(set/union newset))
|
||||||
)))
|
)))
|
||||||
|
|
||||||
(defpath
|
(defnav
|
||||||
^{:doc "Navigates to the specified submap (using select-keys).
|
^{:doc "Navigates to the specified submap (using select-keys).
|
||||||
In a transform, that submap in the original map is changed to the new
|
In a transform, that submap in the original map is changed to the new
|
||||||
value of the submap."}
|
value of the submap."}
|
||||||
|
|
@ -236,7 +236,7 @@
|
||||||
(merge (reduce dissoc structure m-keys)
|
(merge (reduce dissoc structure m-keys)
|
||||||
newmap))))
|
newmap))))
|
||||||
|
|
||||||
(defpath
|
(defnav
|
||||||
walker
|
walker
|
||||||
[afn]
|
[afn]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
|
|
@ -244,7 +244,7 @@
|
||||||
(transform* [this structure next-fn]
|
(transform* [this structure next-fn]
|
||||||
(i/walk-until afn next-fn structure)))
|
(i/walk-until afn next-fn structure)))
|
||||||
|
|
||||||
(defpath
|
(defnav
|
||||||
codewalker
|
codewalker
|
||||||
[afn]
|
[afn]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
|
|
@ -260,7 +260,7 @@
|
||||||
children in the same order when executed on \"select\" and then
|
children in the same order when executed on \"select\" and then
|
||||||
\"transform\"."
|
\"transform\"."
|
||||||
[& path]
|
[& path]
|
||||||
(fixed-pathed-path [late path]
|
(fixed-pathed-nav [late path]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn (compiled-select late structure)))
|
(next-fn (compiled-select late structure)))
|
||||||
(transform* [this structure next-fn]
|
(transform* [this structure next-fn]
|
||||||
|
|
@ -273,7 +273,7 @@
|
||||||
next-val))
|
next-val))
|
||||||
structure)))))
|
structure)))))
|
||||||
|
|
||||||
(defpath
|
(defnav
|
||||||
^{:doc "Navigates to the specified key, navigating to nil if it does not exist."}
|
^{:doc "Navigates to the specified key, navigating to nil if it does not exist."}
|
||||||
keypath
|
keypath
|
||||||
[key]
|
[key]
|
||||||
|
|
@ -283,7 +283,7 @@
|
||||||
(assoc structure key (next-fn (get structure key)))
|
(assoc structure key (next-fn (get structure key)))
|
||||||
))
|
))
|
||||||
|
|
||||||
(defpath
|
(defnav
|
||||||
^{:doc "Navigates to the key only if it exists in the map."}
|
^{:doc "Navigates to the key only if it exists in the map."}
|
||||||
must
|
must
|
||||||
[k]
|
[k]
|
||||||
|
|
@ -296,7 +296,7 @@
|
||||||
structure
|
structure
|
||||||
)))
|
)))
|
||||||
|
|
||||||
(defpath
|
(defnav
|
||||||
^{:doc "Navigates to result of running `afn` on the currently navigated value."}
|
^{:doc "Navigates to result of running `afn` on the currently navigated value."}
|
||||||
view
|
view
|
||||||
[afn]
|
[afn]
|
||||||
|
|
@ -306,14 +306,14 @@
|
||||||
(next-fn (afn structure))
|
(next-fn (afn structure))
|
||||||
))
|
))
|
||||||
|
|
||||||
(defpath parser [parse-fn unparse-fn]
|
(defnav parser [parse-fn unparse-fn]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn (parse-fn structure)))
|
(next-fn (parse-fn structure)))
|
||||||
(transform* [this structure next-fn]
|
(transform* [this structure next-fn]
|
||||||
(unparse-fn (next-fn (parse-fn structure)))
|
(unparse-fn (next-fn (parse-fn structure)))
|
||||||
))
|
))
|
||||||
|
|
||||||
(defpath
|
(defnav
|
||||||
^{:doc "Navigates to atom value."}
|
^{:doc "Navigates to atom value."}
|
||||||
ATOM
|
ATOM
|
||||||
[]
|
[]
|
||||||
|
|
@ -333,7 +333,7 @@
|
||||||
will be parameterized in the order of which the parameterized navigators
|
will be parameterized in the order of which the parameterized navigators
|
||||||
were declared."
|
were declared."
|
||||||
[& path]
|
[& path]
|
||||||
(fixed-pathed-path [late path]
|
(fixed-pathed-nav [late path]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(i/filter-select
|
(i/filter-select
|
||||||
#(i/selected?* late %)
|
#(i/selected?* late %)
|
||||||
|
|
@ -346,7 +346,7 @@
|
||||||
next-fn))))
|
next-fn))))
|
||||||
|
|
||||||
(defpathedfn not-selected? [& path]
|
(defpathedfn not-selected? [& path]
|
||||||
(fixed-pathed-path [late path]
|
(fixed-pathed-nav [late path]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(i/filter-select
|
(i/filter-select
|
||||||
#(i/not-selected?* late %)
|
#(i/not-selected?* late %)
|
||||||
|
|
@ -377,14 +377,14 @@
|
||||||
will be parameterized in the order of which the parameterized navigators
|
will be parameterized in the order of which the parameterized navigators
|
||||||
were declared."
|
were declared."
|
||||||
[path update-fn]
|
[path update-fn]
|
||||||
(fixed-pathed-path [late path]
|
(fixed-pathed-nav [late path]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn (compiled-transform late update-fn structure)))
|
(next-fn (compiled-transform late update-fn structure)))
|
||||||
(transform* [this structure next-fn]
|
(transform* [this structure next-fn]
|
||||||
(next-fn (compiled-transform late update-fn structure)))))
|
(next-fn (compiled-transform late update-fn structure)))))
|
||||||
|
|
||||||
(extend-type #+clj clojure.lang.Keyword #+cljs cljs.core/Keyword
|
(extend-type #+clj clojure.lang.Keyword #+cljs cljs.core/Keyword
|
||||||
StructurePath
|
Navigator
|
||||||
(select* [kw structure next-fn]
|
(select* [kw structure next-fn]
|
||||||
(next-fn (get structure kw)))
|
(next-fn (get structure kw)))
|
||||||
(transform* [kw structure next-fn]
|
(transform* [kw structure next-fn]
|
||||||
|
|
@ -392,14 +392,14 @@
|
||||||
))
|
))
|
||||||
|
|
||||||
(extend-type #+clj clojure.lang.AFn #+cljs function
|
(extend-type #+clj clojure.lang.AFn #+cljs function
|
||||||
StructurePath
|
Navigator
|
||||||
(select* [afn structure next-fn]
|
(select* [afn structure next-fn]
|
||||||
(i/filter-select afn structure next-fn))
|
(i/filter-select afn structure next-fn))
|
||||||
(transform* [afn structure next-fn]
|
(transform* [afn structure next-fn]
|
||||||
(i/filter-transform afn structure next-fn)))
|
(i/filter-transform afn structure next-fn)))
|
||||||
|
|
||||||
(extend-type #+clj clojure.lang.PersistentHashSet #+cljs cljs.core/PersistentHashSet
|
(extend-type #+clj clojure.lang.PersistentHashSet #+cljs cljs.core/PersistentHashSet
|
||||||
StructurePath
|
Navigator
|
||||||
(select* [aset structure next-fn]
|
(select* [aset structure next-fn]
|
||||||
(i/filter-select aset structure next-fn))
|
(i/filter-select aset structure next-fn))
|
||||||
(transform* [aset structure next-fn]
|
(transform* [aset structure next-fn]
|
||||||
|
|
@ -412,7 +412,7 @@
|
||||||
i/pred*
|
i/pred*
|
||||||
)
|
)
|
||||||
|
|
||||||
(defpath
|
(defnav
|
||||||
^{:doc "Navigates to the provided val if the structure is nil. Otherwise it stays
|
^{:doc "Navigates to the provided val if the structure is nil. Otherwise it stays
|
||||||
navigated at the structure."}
|
navigated at the structure."}
|
||||||
nil->val
|
nil->val
|
||||||
|
|
@ -462,7 +462,7 @@
|
||||||
will be parameterized in the order of which the parameterized navigators
|
will be parameterized in the order of which the parameterized navigators
|
||||||
were declared."
|
were declared."
|
||||||
[& conds]
|
[& conds]
|
||||||
(variable-pathed-path [compiled-paths conds]
|
(variable-pathed-nav [compiled-paths conds]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(if-let [selector (i/retrieve-cond-selector compiled-paths structure)]
|
(if-let [selector (i/retrieve-cond-selector compiled-paths structure)]
|
||||||
(->> (compiled-select selector structure)
|
(->> (compiled-select selector structure)
|
||||||
|
|
@ -484,7 +484,7 @@
|
||||||
"A path that branches on multiple paths. For updates,
|
"A path that branches on multiple paths. For updates,
|
||||||
applies updates to the paths in order."
|
applies updates to the paths in order."
|
||||||
[& paths]
|
[& paths]
|
||||||
(variable-pathed-path [compiled-paths paths]
|
(variable-pathed-nav [compiled-paths paths]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(->> compiled-paths
|
(->> compiled-paths
|
||||||
(mapcat #(compiled-select % structure))
|
(mapcat #(compiled-select % structure))
|
||||||
|
|
|
||||||
|
|
@ -67,9 +67,9 @@
|
||||||
(apply transform-fn (conj vals structure))))))
|
(apply transform-fn (conj vals structure))))))
|
||||||
))
|
))
|
||||||
|
|
||||||
(def StructurePathExecutor
|
(def LeanPathExecutor
|
||||||
(->ExecutorFunctions
|
(->ExecutorFunctions
|
||||||
:spath
|
:leanpath
|
||||||
(fn [params params-idx selector structure]
|
(fn [params params-idx selector structure]
|
||||||
(selector structure (fn [structure] [structure])))
|
(selector structure (fn [structure] [structure])))
|
||||||
(fn [params params-idx transformer transform-fn structure]
|
(fn [params params-idx transformer transform-fn structure]
|
||||||
|
|
@ -158,8 +158,8 @@
|
||||||
(defn structure-path-impl [this]
|
(defn structure-path-impl [this]
|
||||||
(if (fn? this)
|
(if (fn? this)
|
||||||
;;TODO: this isn't kosher, it uses knowledge of internals of protocols
|
;;TODO: this isn't kosher, it uses knowledge of internals of protocols
|
||||||
(-> p/StructurePath :impls (get clojure.lang.AFn))
|
(-> p/Navigator :impls (get clojure.lang.AFn))
|
||||||
(find-protocol-impl! p/StructurePath this)))
|
(find-protocol-impl! p/Navigator this)))
|
||||||
|
|
||||||
#+clj
|
#+clj
|
||||||
(defn collector-impl [this]
|
(defn collector-impl [this]
|
||||||
|
|
@ -168,8 +168,8 @@
|
||||||
|
|
||||||
#+cljs
|
#+cljs
|
||||||
(defn structure-path-impl [obj]
|
(defn structure-path-impl [obj]
|
||||||
{:select* (mk-optimized-invocation p/StructurePath obj select* 2)
|
{:select* (mk-optimized-invocation p/Navigator obj select* 2)
|
||||||
:transform* (mk-optimized-invocation p/StructurePath obj transform* 2)
|
:transform* (mk-optimized-invocation p/Navigator obj transform* 2)
|
||||||
})
|
})
|
||||||
|
|
||||||
#+cljs
|
#+cljs
|
||||||
|
|
@ -196,7 +196,7 @@
|
||||||
transformer (:transform* pimpl)]
|
transformer (:transform* pimpl)]
|
||||||
(no-params-compiled-path
|
(no-params-compiled-path
|
||||||
(->TransformFunctions
|
(->TransformFunctions
|
||||||
StructurePathExecutor
|
LeanPathExecutor
|
||||||
(fn [structure next-fn]
|
(fn [structure next-fn]
|
||||||
(selector this structure next-fn))
|
(selector this structure next-fn))
|
||||||
(fn [structure next-fn]
|
(fn [structure next-fn]
|
||||||
|
|
@ -217,7 +217,7 @@
|
||||||
)))
|
)))
|
||||||
|
|
||||||
(defn structure-path? [obj]
|
(defn structure-path? [obj]
|
||||||
(or (fn? obj) (satisfies? p/StructurePath obj)))
|
(or (fn? obj) (satisfies? p/Navigator obj)))
|
||||||
|
|
||||||
(defprotocol CoercePath
|
(defprotocol CoercePath
|
||||||
(coerce-path [this]))
|
(coerce-path [this]))
|
||||||
|
|
@ -528,10 +528,10 @@
|
||||||
(into empty-structure (map #(next-fn %)) structure)
|
(into empty-structure (map #(next-fn %)) structure)
|
||||||
)))
|
)))
|
||||||
|
|
||||||
(deftype AllStructurePath [])
|
(deftype AllNavigator [])
|
||||||
|
|
||||||
(extend-protocol p/StructurePath
|
(extend-protocol p/Navigator
|
||||||
AllStructurePath
|
AllNavigator
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(all-select structure next-fn))
|
(all-select structure next-fn))
|
||||||
(transform* [this structure next-fn]
|
(transform* [this structure next-fn]
|
||||||
|
|
@ -544,10 +544,10 @@
|
||||||
(collect-val [this structure]
|
(collect-val [this structure]
|
||||||
structure))
|
structure))
|
||||||
|
|
||||||
(deftype PosStructurePath [getter setter])
|
(deftype PosNavigator [getter setter])
|
||||||
|
|
||||||
(extend-protocol p/StructurePath
|
(extend-protocol p/Navigator
|
||||||
PosStructurePath
|
PosNavigator
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(if-not (empty? structure)
|
(if-not (empty? structure)
|
||||||
(next-fn ((.-getter this) structure))))
|
(next-fn ((.-getter this) structure))))
|
||||||
|
|
@ -570,7 +570,7 @@
|
||||||
res
|
res
|
||||||
)))
|
)))
|
||||||
|
|
||||||
(extend-protocol p/StructurePath
|
(extend-protocol p/Navigator
|
||||||
nil
|
nil
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn structure))
|
(next-fn structure))
|
||||||
|
|
@ -724,8 +724,7 @@
|
||||||
(instance? VarUse p)
|
(instance? VarUse p)
|
||||||
(let [v (:var p)
|
(let [v (:var p)
|
||||||
vv (var-get v)]
|
vv (var-get v)]
|
||||||
(cond (-> v meta :dynamic)
|
(cond (-> v meta :dynamic) (magic-fail! "Var " (:sym p) " is dynamic")
|
||||||
(magic-fail! "Var " (:sym p) " is dynamic")
|
|
||||||
(valid-navigator? vv) vv
|
(valid-navigator? vv) vv
|
||||||
:else (magic-fail! "Var " (:sym p) " is not a navigator")
|
:else (magic-fail! "Var " (:sym p) " is not a navigator")
|
||||||
))
|
))
|
||||||
|
|
|
||||||
|
|
@ -19,14 +19,14 @@
|
||||||
(def PARAMS-SYM (vary-meta (gensym "params") assoc :tag 'objects))
|
(def PARAMS-SYM (vary-meta (gensym "params") assoc :tag 'objects))
|
||||||
(def PARAMS-IDX-SYM (gensym "params-idx"))
|
(def PARAMS-IDX-SYM (gensym "params-idx"))
|
||||||
|
|
||||||
(defn paramspath* [bindings num-params [impl1 impl2]]
|
(defn paramsnav* [bindings num-params [impl1 impl2]]
|
||||||
(let [[[[_ s-structure-sym s-next-fn-sym] & select-body]
|
(let [[[[_ s-structure-sym s-next-fn-sym] & select-body]
|
||||||
[[_ t-structure-sym t-next-fn-sym] & transform-body]]
|
[[_ t-structure-sym t-next-fn-sym] & transform-body]]
|
||||||
(determine-params-impls impl1 impl2)]
|
(determine-params-impls impl1 impl2)]
|
||||||
(if (= 0 num-params)
|
(if (= 0 num-params)
|
||||||
`(i/no-params-compiled-path
|
`(i/no-params-compiled-path
|
||||||
(i/->TransformFunctions
|
(i/->TransformFunctions
|
||||||
i/StructurePathExecutor
|
i/LeanPathExecutor
|
||||||
(fn [~s-structure-sym ~s-next-fn-sym]
|
(fn [~s-structure-sym ~s-next-fn-sym]
|
||||||
~@select-body)
|
~@select-body)
|
||||||
(fn [~t-structure-sym ~t-next-fn-sym]
|
(fn [~t-structure-sym ~t-next-fn-sym]
|
||||||
|
|
@ -76,7 +76,7 @@
|
||||||
~num-params
|
~num-params
|
||||||
)))
|
)))
|
||||||
|
|
||||||
(defn pathed-path* [builder paths-seq latefns-sym pre-bindings post-bindings impls]
|
(defn pathed-nav* [builder paths-seq latefns-sym pre-bindings post-bindings impls]
|
||||||
(let [num-params-sym (gensym "num-params")]
|
(let [num-params-sym (gensym "num-params")]
|
||||||
`(let [paths# (map i/comp-paths* ~paths-seq)
|
`(let [paths# (map i/comp-paths* ~paths-seq)
|
||||||
needed-params# (map i/num-needed-params paths#)
|
needed-params# (map i/num-needed-params paths#)
|
||||||
|
|
@ -114,19 +114,19 @@
|
||||||
(apply concat)))
|
(apply concat)))
|
||||||
|
|
||||||
|
|
||||||
(defmacro path
|
(defmacro nav
|
||||||
"Defines a StructurePath with late bound parameters. This path can be precompiled
|
"Defines a navigator with late bound parameters. This navigator can be precompiled
|
||||||
with other selectors without knowing the parameters. When precompiled with other
|
with other navigators without knowing the parameters. When precompiled with other
|
||||||
selectors, the resulting selector takes in parameters for all selectors in the path
|
navigators, the resulting path takes in parameters for all navigators in the path
|
||||||
that needed parameters (in the order in which they were declared)."
|
that needed parameters (in the order in which they were declared)."
|
||||||
[params impl1 impl2]
|
[params impl1 impl2]
|
||||||
(let [num-params (count params)
|
(let [num-params (count params)
|
||||||
retrieve-params (make-param-retrievers params)]
|
retrieve-params (make-param-retrievers params)]
|
||||||
(paramspath* retrieve-params num-params [impl1 impl2])
|
(paramsnav* retrieve-params num-params [impl1 impl2])
|
||||||
))
|
))
|
||||||
|
|
||||||
(defmacro paramsfn [params [structure-sym] & impl]
|
(defmacro paramsfn [params [structure-sym] & impl]
|
||||||
`(path ~params
|
`(nav ~params
|
||||||
(~'select* [this# structure# next-fn#]
|
(~'select* [this# structure# next-fn#]
|
||||||
(let [afn# (fn [~structure-sym] ~@impl)]
|
(let [afn# (fn [~structure-sym] ~@impl)]
|
||||||
(i/filter-select afn# structure# next-fn#)
|
(i/filter-select afn# structure# next-fn#)
|
||||||
|
|
@ -148,16 +148,16 @@
|
||||||
(paramscollector* retrieve-params num-params impl)
|
(paramscollector* retrieve-params num-params impl)
|
||||||
))
|
))
|
||||||
|
|
||||||
(defmacro defpath [name & body]
|
(defmacro defnav [name & body]
|
||||||
`(def ~name (path ~@body)))
|
`(def ~name (nav ~@body)))
|
||||||
|
|
||||||
(defmacro defcollector [name & body]
|
(defmacro defcollector [name & body]
|
||||||
`(def ~name (paramscollector ~@body)))
|
`(def ~name (paramscollector ~@body)))
|
||||||
|
|
||||||
(defmacro fixed-pathed-path
|
(defmacro fixed-pathed-nav
|
||||||
"This helper is used to define selectors that take in a fixed number of other selector
|
"This helper is used to define navigators that take in a fixed number of other
|
||||||
paths as input. Those selector paths may require late-bound params, so this helper
|
paths as input. Those paths may require late-bound params, so this helper
|
||||||
will create a parameterized selector if that is the case. If no late-bound params
|
will create a parameterized navigator if that is the case. If no late-bound params
|
||||||
are required, then the result is executable."
|
are required, then the result is executable."
|
||||||
[bindings impl1 impl2]
|
[bindings impl1 impl2]
|
||||||
(let [bindings (partition 2 bindings)
|
(let [bindings (partition 2 bindings)
|
||||||
|
|
@ -165,23 +165,23 @@
|
||||||
names (mapv first bindings)
|
names (mapv first bindings)
|
||||||
latefns-sym (gensym "latefns")
|
latefns-sym (gensym "latefns")
|
||||||
latefn-syms (vec (gensyms (count paths)))]
|
latefn-syms (vec (gensyms (count paths)))]
|
||||||
(pathed-path*
|
(pathed-nav*
|
||||||
paramspath*
|
paramsnav*
|
||||||
paths
|
paths
|
||||||
latefns-sym
|
latefns-sym
|
||||||
[latefn-syms latefns-sym]
|
[latefn-syms latefns-sym]
|
||||||
(mapcat (fn [n l] [n `(~l ~PARAMS-SYM ~PARAMS-IDX-SYM)]) names latefn-syms)
|
(mapcat (fn [n l] [n `(~l ~PARAMS-SYM ~PARAMS-IDX-SYM)]) names latefn-syms)
|
||||||
[impl1 impl2])))
|
[impl1 impl2])))
|
||||||
|
|
||||||
(defmacro variable-pathed-path
|
(defmacro variable-pathed-nav
|
||||||
"This helper is used to define selectors that take in a variable number of other selector
|
"This helper is used to define navigators that take in a variable number of other
|
||||||
paths as input. Those selector paths may require late-bound params, so this helper
|
paths as input. Those paths may require late-bound params, so this helper
|
||||||
will create a parameterized selector if that is the case. If no late-bound params
|
will create a parameterized navigator if that is the case. If no late-bound params
|
||||||
are required, then the result is executable."
|
are required, then the result is executable."
|
||||||
[[latepaths-seq-sym paths-seq] impl1 impl2]
|
[[latepaths-seq-sym paths-seq] impl1 impl2]
|
||||||
(let [latefns-sym (gensym "latefns")]
|
(let [latefns-sym (gensym "latefns")]
|
||||||
(pathed-path*
|
(pathed-nav*
|
||||||
paramspath*
|
paramsnav*
|
||||||
paths-seq
|
paths-seq
|
||||||
latefns-sym
|
latefns-sym
|
||||||
[]
|
[]
|
||||||
|
|
@ -198,7 +198,7 @@
|
||||||
[[name path] impl]
|
[[name path] impl]
|
||||||
(let [latefns-sym (gensym "latefns")
|
(let [latefns-sym (gensym "latefns")
|
||||||
latefn (gensym "latefn")]
|
latefn (gensym "latefn")]
|
||||||
(pathed-path*
|
(pathed-nav*
|
||||||
paramscollector*
|
paramscollector*
|
||||||
[path]
|
[path]
|
||||||
latefns-sym
|
latefns-sym
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
(ns com.rpl.specter.protocols)
|
(ns com.rpl.specter.protocols)
|
||||||
|
|
||||||
(defprotocol StructurePath
|
(defprotocol Navigator
|
||||||
(select* [this structure next-fn])
|
(select* [this structure next-fn])
|
||||||
(transform* [this structure next-fn]))
|
(transform* [this structure next-fn]))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
(ns com.rpl.specter.zipper
|
(ns com.rpl.specter.zipper
|
||||||
#+cljs (:require-macros
|
#+cljs (:require-macros
|
||||||
[com.rpl.specter.macros
|
[com.rpl.specter.macros
|
||||||
:refer [defpath path declarepath providepath]])
|
:refer [defnav nav declarepath providepath]])
|
||||||
#+clj
|
#+clj
|
||||||
(:use
|
(:use
|
||||||
[com.rpl.specter.macros :only [defpath path declarepath providepath]])
|
[com.rpl.specter.macros :only [defnav nav declarepath providepath]])
|
||||||
(:require [com.rpl.specter :as s]
|
(:require [com.rpl.specter :as s]
|
||||||
[clojure.zip :as zip]))
|
[clojure.zip :as zip]))
|
||||||
|
|
||||||
(defpath zipper [constructor]
|
(defnav zipper [constructor]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn (constructor structure)))
|
(next-fn (constructor structure)))
|
||||||
(transform* [this structure next-fn]
|
(transform* [this structure next-fn]
|
||||||
|
|
@ -30,14 +30,14 @@
|
||||||
s/STAY)))
|
s/STAY)))
|
||||||
|
|
||||||
|
|
||||||
(defn- mk-zip-nav [nav]
|
(defn- mk-zip-nav [znav]
|
||||||
(path []
|
(nav []
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(let [ret (nav structure)]
|
(let [ret (znav structure)]
|
||||||
(if ret (next-fn ret))
|
(if ret (next-fn ret))
|
||||||
))
|
))
|
||||||
(transform* [this structure next-fn]
|
(transform* [this structure next-fn]
|
||||||
(let [ret (nav structure)]
|
(let [ret (znav structure)]
|
||||||
(if ret (next-fn ret) structure)
|
(if ret (next-fn ret) structure)
|
||||||
))))
|
))))
|
||||||
|
|
||||||
|
|
@ -76,7 +76,7 @@
|
||||||
inserts)
|
inserts)
|
||||||
))
|
))
|
||||||
|
|
||||||
(defpath ^{:doc "Navigate to the empty subsequence directly to the
|
(defnav ^{:doc "Navigate to the empty subsequence directly to the
|
||||||
right of this element."}
|
right of this element."}
|
||||||
INNER-RIGHT []
|
INNER-RIGHT []
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
|
|
@ -85,7 +85,7 @@
|
||||||
(inner-insert structure next-fn zip/insert-right zip/right zip/left)
|
(inner-insert structure next-fn zip/insert-right zip/right zip/left)
|
||||||
))
|
))
|
||||||
|
|
||||||
(defpath ^{:doc "Navigate to the empty subsequence directly to the
|
(defnav ^{:doc "Navigate to the empty subsequence directly to the
|
||||||
left of this element."}
|
left of this element."}
|
||||||
INNER-LEFT []
|
INNER-LEFT []
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
|
|
@ -94,7 +94,7 @@
|
||||||
(inner-insert structure next-fn zip/insert-left identity nil)
|
(inner-insert structure next-fn zip/insert-left identity nil)
|
||||||
))
|
))
|
||||||
|
|
||||||
(defpath NODE []
|
(defnav NODE []
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn (zip/node structure))
|
(next-fn (zip/node structure))
|
||||||
)
|
)
|
||||||
|
|
@ -102,7 +102,7 @@
|
||||||
(zip/edit structure next-fn)
|
(zip/edit structure next-fn)
|
||||||
))
|
))
|
||||||
|
|
||||||
(defpath ^{:doc "Navigate to the subsequence containing only
|
(defnav ^{:doc "Navigate to the subsequence containing only
|
||||||
the node currently pointed to. This works just
|
the node currently pointed to. This works just
|
||||||
like srange and can be used to remove elements
|
like srange and can be used to remove elements
|
||||||
from the structure"}
|
from the structure"}
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,15 @@
|
||||||
[cljs.test.check.cljs-test :refer [defspec]]
|
[cljs.test.check.cljs-test :refer [defspec]]
|
||||||
[com.rpl.specter.cljs-test-helpers :refer [for-all+]]
|
[com.rpl.specter.cljs-test-helpers :refer [for-all+]]
|
||||||
[com.rpl.specter.macros
|
[com.rpl.specter.macros
|
||||||
:refer [paramsfn defprotocolpath defpath extend-protocolpath
|
:refer [paramsfn defprotocolpath defnav extend-protocolpath
|
||||||
declarepath providepath]])
|
nav declarepath providepath]])
|
||||||
(:use
|
(:use
|
||||||
#+clj [clojure.test :only [deftest is]]
|
#+clj [clojure.test :only [deftest is]]
|
||||||
#+clj [clojure.test.check.clojure-test :only [defspec]]
|
#+clj [clojure.test.check.clojure-test :only [defspec]]
|
||||||
#+clj [com.rpl.specter.test-helpers :only [for-all+]]
|
#+clj [com.rpl.specter.test-helpers :only [for-all+]]
|
||||||
#+clj [com.rpl.specter.macros
|
#+clj [com.rpl.specter.macros
|
||||||
:only [paramsfn defprotocolpath defpath extend-protocolpath
|
:only [paramsfn defprotocolpath defnav extend-protocolpath
|
||||||
declarepath providepath]]
|
nav declarepath providepath]]
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -603,8 +603,8 @@
|
||||||
val (gen/elements (range 10))
|
val (gen/elements (range 10))
|
||||||
op (gen/elements [inc dec])
|
op (gen/elements [inc dec])
|
||||||
comparator (gen/elements [= > <])]
|
comparator (gen/elements [= > <])]
|
||||||
(let [path (s/comp-paths s/ALL (paramsfn [p] [v] (comparator v p)))]
|
(let [cpath (s/comp-paths s/ALL (paramsfn [p] [v] (comparator v p)))]
|
||||||
(= (s/transform (path val) op v)
|
(= (s/transform (cpath val) op v)
|
||||||
(s/transform [s/ALL #(comparator % val)] op v)))
|
(s/transform [s/ALL #(comparator % val)] op v)))
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue