diff options
Diffstat (limited to 'macros.lisp')
-rw-r--r-- | macros.lisp | 48 |
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|))))) |