summaryrefslogtreecommitdiff
path: root/macros.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'macros.lisp')
-rw-r--r--macros.lisp48
1 files changed, 48 insertions, 0 deletions
diff --git a/macros.lisp b/macros.lisp
new file mode 100644
index 0000000..4466105
--- /dev/null
+++ b/macros.lisp
@@ -0,0 +1,48 @@
+(in-package :granolin)
+
+(defmacro let-cond ((var) &body forms)
+ `(let (,var)
+ (cond
+ ,@(loop :for form :in forms
+ :collect (destructuring-bind (test . actions) form
+ `((setf ,var ,test) ,@actions))))))
+(defmacro let-when ((var test) &body body)
+ `(let ((,var ,test))
+ (when ,test ,@body)))
+
+(defmacro let-if ((var test) then &optional else)
+ `(let ((,var ,test))
+ (if ,test ,then ,else)))
+
+(defmacro getob (ob key &rest keys)
+ "OB should be a nested PLIST, KEYS are lists of keys into that PLIST. Gets the
+ result of nested GETF calls into the list. This form is SETF-able."
+ (let ((form `(getf ,ob ,key)))
+ (dolist (k keys)
+ (setf form `(getf ,form ,k)))
+ form))
+
+
+(defmacro def-json-wrap (name &rest field-specs)
+ "Defines a struct named the value of NAME, a symbol, with a single slot called
+ DATA. DATA holds a PLIST as returned by JONATHAN:PARSE.
+
+ Each FIELD-SPEC is a list of the form (METHOD-NAME KEY1 ... KEYN)
+
+ For each FIELD-SPEC, a method called METHOD-NAME will be defined as a reader
+ that accesses a value, the path to which is formed of the KEY values.
+
+ E.g. If a JSON value `ob` has a descendent at `ob.x.y.z` then the FIELD-SPEC
+ could be (get-z :|x| :|y| :|z|)
+ "
+ `(progn
+ (defstruct ,name data)
+ ,@(loop :for (method . keys) :in field-specs :collect
+ `(defmethod ,method ((ob ,name))
+ (with-slots (data) ob
+ (getob data ,@keys))))))
+
+(defmacro def-timeline-event-pred (name etype mtype)
+ `(defun ,name (event)
+ (and (equal ,etype (getob event :|type|))
+ (equal ,mtype (getob event :|content| :|msgtype|)))))