Skip to content

Commit

Permalink
Added ':as request' syntax to vector bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
weavejester committed Dec 26, 2010
1 parent cbe0831 commit 7bfdb21
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 7 deletions.
28 changes: 21 additions & 7 deletions src/compojure/core.clj
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -38,21 +38,35 @@
[request params] [request params]
(merge-with merge request {:route-params params, :params params})) (merge-with merge request {:route-params params, :params params}))


(defn- param-vector-bindings (defn- assoc-&-binding [binds req sym]
(assoc binds sym `(dissoc (:params ~req) ~@(map keyword (keys binds)))))

(defn- assoc-symbol-binding [binds req sym]
(assoc binds sym `(get-in ~req [:params ~(keyword sym)])))

(defn- vector-bindings
"Create the bindings for a vector of parameters." "Create the bindings for a vector of parameters."
[request bindings body] [args req]
(let [[args [_ more]] (split-with #(not= % '&) bindings)] (loop [args args, binds {}]
`(let [{:keys ~(vec args)} (~request :params) (if-let [sym (first args)]
~@(if more [more `(dissoc (~request :params) ~@(map keyword args))])] (cond
~@body))) (= '& sym)
(recur (nnext args) (assoc-&-binding binds req (second args)))
(= :as sym)
(recur (nnext args) (assoc binds (second args) req))
(symbol? sym)
(recur (next args) (assoc-symbol-binding binds req sym))
:else
(throw (Exception. (str "Unexpected binding: " sym))))
(mapcat identity binds))))


(defmacro bind-request (defmacro bind-request
"Bind a request to a collection of symbols. The collection can be a Clojure "Bind a request to a collection of symbols. The collection can be a Clojure
map destructuring binding for the request map, or it can be a vector of map destructuring binding for the request map, or it can be a vector of
parameter bindings." parameter bindings."
[request bindings & body] [request bindings & body]
(if (vector? bindings) (if (vector? bindings)
(param-vector-bindings request bindings body) `(let [~@(vector-bindings bindings request)] ~@body)
`(let [~bindings ~request] ~@body))) `(let [~bindings ~request] ~@body)))


(defn- compile-route (defn- compile-route
Expand Down
10 changes: 10 additions & 0 deletions test/compojure/test/core.clj
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@
nil) nil)
(-> (request :get "/foo") (-> (request :get "/foo")
(assoc :params {:y "bar", :z "baz"})))) (assoc :params {:y "bar", :z "baz"}))))

(testing "vector ':as request' arguments"
(let [req (-> (request :get "/foo")
(assoc :params {:y "bar"}))]
((GET "/:x" [x :as r]
(is (= x "foo"))
(is (= (dissoc r :params :route-params)
(dissoc req :params)))
nil)
req)))


(testing "map arguments" (testing "map arguments"
((GET "/foo" {params :params} ((GET "/foo" {params :params}
Expand Down

0 comments on commit 7bfdb21

Please sign in to comment.