Skip to content

Commit

Permalink
support :with option
Browse files Browse the repository at this point in the history
  • Loading branch information
robertluo committed May 30, 2020
1 parent 19be97d commit 1e17d08
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 5 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ from the collection starting from index 10 (0 based), and take 20.

If a value is not present in data, its value pulled will be `:robertluo.pullable.core/not-found` by default. However, you can specific it by using `:not-found 0` to change it.

### `:with` option

If a value is a function, you can pass `:with` arguments, it will apply these arguments to the function and return it.

## License
Copyright © 2020 Robertluo

Expand Down
21 changes: 18 additions & 3 deletions src/robertluo/pullable/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
sub-data
(vals processors)))
(catch Exception ex
(let [err #:error{:key key :message (ex-message ex)}]
(let [err (merge (ex-data ex) #:error{:key key :message (ex-message ex)})]
((or ex-handler identity) err))))]
(if key {key v} v))))

Expand All @@ -55,6 +55,9 @@
(->> (map #(-select % elem) children)
(apply merge)))

(defn error [msg value]
(throw (ex-info msg {:error/value value})))

(defrecord CoreProcessor []
Processor
(-process
Expand All @@ -69,12 +72,20 @@
(-process
[_ data children]
(cond
(map? data) (throw (ex-info "Map is not considered as a seq" {:data data}))
(not (seq data)) (throw (ex-info "Not a seq" {:data data}))
(map? data) (error "Map is not considered as a seq" data)
(not (seq data)) (error "Not a seq" data)
:else (cond->> (map #(select-merge % children) data)
offset (drop offset)
limit (take limit)))))

(defrecord WithProcessor [args]
Processor
(-process
[_ data _]
(if (fn? data)
(apply data args)
(error "Not a function" data))))

(defrecord NotFoundProcessor [default]
Processor
(-process
Expand Down Expand Up @@ -106,6 +117,10 @@
(let [[offset limit] s]
[::core (SeqProcessor. offset limit)]))

(defmethod option-create :with
[[_ args]]
[::with (WithProcessor. args)])

(defn mk-processors
"returns a creator array map for options kv"
[options]
Expand Down
8 changes: 8 additions & 0 deletions test/robertluo/pullable/core_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@
(is (= {::sut/core (sut/->CoreProcessor) ::sut/not-found (sut/->NotFoundProcessor :foo)}
(sut/mk-processors {:not-found :foo})))))

(deftest with-option
(testing "for with option, try call function"
(is (= {:foo 2}
(sut/-select (sut/query {:key :foo} {:with [1]}) {:foo inc}))))
(testing "if it is not a function, with function will return an error"
(is (= {:foo #:error{:key :foo :value 1 :message "Not a function"}}
(sut/-select (sut/query {:key :foo} {:with [1]}) {:foo 1})))))

(deftest not-found-option
(testing "a query with :not-found specified will return it"
(is (= {:bar 0}
Expand Down
8 changes: 6 additions & 2 deletions test/robertluo/pullable_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
:recur [{:int 10 :recur [{:int 100 :recur [{:int 1000}]}]}
{:int 20 :recur [{:int 200 :recur [{:int 2000 :recur [{:int 20000}]}]}]}]
:vec [{:int 5} {:int 8
:kw :bar}]} }]
:kw :bar}]}
:fn str}]
(testing "simple pull pattern"
(is (= {:int 8} (sut/pull data :int))))
(testing "complex pattern"
Expand All @@ -33,4 +34,7 @@
(is (= [8 :map] ((juxt :int #(get-in % [:map :error/key])) exp)))))
(testing "can pull in a root sequence"
(is (= [{:int 8} {:int 8}]
(sut/pull [data data] '([:int] :seq [])))))))
(sut/pull [data data] '([:int] :seq [])))))
(testing "pull with a :with option, will call the value as a function"
(is (= {:fn "hello world"}
(sut/pull data '(:fn :with ["hello" " " "world"])))))))

0 comments on commit 1e17d08

Please sign in to comment.