diff --git a/src/com/rpl/specter.cljc b/src/com/rpl/specter.cljc index 10f1619..8f939ca 100644 --- a/src/com/rpl/specter.cljc +++ b/src/com/rpl/specter.cljc @@ -58,8 +58,8 @@ [selector structure] (compiled-select-first (i/comp-paths* selector) structure)) -;; Transformfunctions +;; Transform functions (def ^{:doc "Version of transform that takes in a selector pre-compiled with comp-paths"} compiled-transform i/compiled-transform*) @@ -114,19 +114,22 @@ (defmacro paramspath [params & impls] (let [num-params (count params) - retrieve-params (->> params - (map-indexed - (fn [i p] - [p `(aget ~i/PARAMS-SYM - (+ ~i/PARAMS-IDX-SYM ~i))] - )) - (apply concat))] + retrieve-params (i/make-param-retrievers params)] (i/paramspath* retrieve-params num-params impls) )) +(defmacro paramscollector [params impl] + (let [num-params (count params) + retrieve-params (i/make-param-retrievers params)] + (i/paramscollector* retrieve-params num-params impl) + )) + (defmacro defparamspath [name & body] `(def ~name (paramspath ~@body))) +(defmacro defparamscollector [name & body] + `(def ~name (paramscollector ~@body))) + (defmacro fixed-pathed-path [bindings & impls] (let [bindings (partition 2 bindings) paths (mapv second bindings) @@ -276,16 +279,17 @@ (defn collect-one [& selector] (i/->SelectCollector select-one (i/comp-paths* selector))) -(defn putval - "Adds an external value to the collected vals. Useful when additional arguments - are required to the transform function that would otherwise require partial - application or a wrapper function. - e.g., incrementing val at path [:a :b] by 3: - (transform [:a :b (putval 3)] + some-map)" - [val] - (i/->PutValCollector val)) +;;TODO: add this comment: +; "Adds an external value to the collected vals. Useful when additional arguments +; are required to the transform function that would otherwise require partial +; application or a wrapper function. +; e.g., incrementing val at path [:a :b] by 3: +; (transform [:a :b (putval 3)] + some-map)" +(defparamscollector putval [val] + (collect* [this structure] + val )) ;;TODO: test nothing matches case (defn cond-path diff --git a/src/com/rpl/specter/impl.cljc b/src/com/rpl/specter/impl.cljc index bb4482d..2edf76d 100644 --- a/src/com/rpl/specter/impl.cljc +++ b/src/com/rpl/specter/impl.cljc @@ -410,6 +410,34 @@ ret# )))) + +(defn paramscollector* [bindings num-params [_ [_ structure-sym] & body]] + `(let [collector# (fn [~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~structure-sym next-fn#] + (let [~@bindings ~@[] ; to avoid syntax highlighting issues + c# (do ~@body)] + (next-fn# + ~PARAMS-SYM + (+ ~PARAMS-IDX-SYM ~num-params) + (conj vals# c#) + ~structure-sym) + ))] + (->ParamsNeededPath + (->TransformFunctions + RichPathExecutor + collector# + collector# ) + ~num-params + ))) + +(defn make-param-retrievers [params] + (->> params + (map-indexed + (fn [i p] + [p `(aget ~PARAMS-SYM + (+ ~PARAMS-IDX-SYM ~i))] + )) + (apply concat))) + ;; cell implementation idea taken from prismatic schema library (defprotocol PMutableCell #?(:clj (get_cell [cell])) diff --git a/src/com/rpl/specter/protocols.cljc b/src/com/rpl/specter/protocols.cljc index 7c13128..d742b98 100644 --- a/src/com/rpl/specter/protocols.cljc +++ b/src/com/rpl/specter/protocols.cljc @@ -6,4 +6,3 @@ (defprotocol Collector (collect-val [this structure])) -