Skip to content
Browse files

Added ':as request' syntax to vector bindings

  • Loading branch information...
1 parent cbe0831 commit 7bfdb21bf86d8f6354a65f5ad350f9d13e081057 @weavejester committed Dec 26, 2010
Showing with 31 additions and 7 deletions.
  1. +21 −7 src/compojure/core.clj
  2. +10 −0 test/compojure/test/core.clj
View
28 src/compojure/core.clj
@@ -38,21 +38,35 @@
[request 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."
- [request bindings body]
- (let [[args [_ more]] (split-with #(not= % '&) bindings)]
- `(let [{:keys ~(vec args)} (~request :params)
- ~@(if more [more `(dissoc (~request :params) ~@(map keyword args))])]
- ~@body)))
+ [args req]
+ (loop [args args, binds {}]
+ (if-let [sym (first args)]
+ (cond
+ (= '& 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
"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
parameter bindings."
[request bindings & body]
(if (vector? bindings)
- (param-vector-bindings request bindings body)
+ `(let [~@(vector-bindings bindings request)] ~@body)
`(let [~bindings ~request] ~@body)))
(defn- compile-route
View
10 test/compojure/test/core.clj
@@ -25,6 +25,16 @@
nil)
(-> (request :get "/foo")
(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"
((GET "/foo" {params :params}

0 comments on commit 7bfdb21

Please sign in to comment.
Something went wrong with that request. Please try again.