aboutsummaryrefslogtreecommitdiff
path: root/src/macros.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'src/macros.lisp')
-rw-r--r--src/macros.lisp49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/macros.lisp b/src/macros.lisp
new file mode 100644
index 0000000..0d941b6
--- /dev/null
+++ b/src/macros.lisp
@@ -0,0 +1,49 @@
+;; Copyright (C) 2022 colin@cicadas.surf
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU Affero General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU Affero General Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+;;;; macros.lisp --- utility macros
+
+
+(in-package :lazybones)
+
+(defmacro let-parameters ((&rest names) &body body)
+ "NAMES is a list of symbols. Binds the names to the value of the
+request parameters whose keys compare string-equal to the symbol-name
+of each NAME, or NIL if there is no such parameter."
+ (let ((params (gensym)))
+ `(let ((,params (lazybones:request-parameters)))
+ (let ,(loop for name in names
+ for string-name = (symbol-name name)
+ collect `(,name (cdr (assoc ,string-name ,params :test #'string-equal))))
+ (declare (ignorable ,@names))
+ ,@body))))
+
+(defmacro map-parameters ((&rest params) &body body)
+ "PARAMS is a list of pairs (NAME PARSER). MAP-PARAMETERS behaves
+exactly like LET-PARAMETERS except that the values boudn to NAMEs are
+first mapped with the PARSER function."
+ (assert (loop for (name parser) in params
+ always (and (symbolp name)
+ (or (symbolp parser) (functionp parser))))
+ ()
+ "Malformed PARAMS in MAP-PARAMETERS macro")
+
+ (let ((names (mapcar #'car params)))
+ `(let-parameters ,names
+ (let ,(loop for name in names
+ collect `(,name (when ,name (funcall ',(second (assoc name params)) ,name))))
+ ,@body))))
+