Paste number 54156: hunchentoot all-powerful handler macro

Paste number 54156: hunchentoot all-powerful handler macro
Pasted by: baggles
7 months, 3 weeks ago
#lispcafe | Context in IRC logs
Paste contents:
Raw Source | XML | Display As

;; for hunchentoot


(defmacro define-handler (name (&rest lambda-args) regex &body forms)
  (let* ((keys lambda-args)
         (named (loop until (or (when (eql (car keys) '&key)
                                  (pop keys)
)

                                (null keys)
)

                   collecting (pop keys)
)
)

         (m0 (gensym "M0-"))
         (m1 (gensym "M1-"))
         (rn0 (gensym "RN0-"))
         (rn1 (gensym "RN1-"))
         (request-path (gensym "REQUEST-PATH-"))
         (request-query (gensym "REQUEST-QUERY-"))
         (key-vals (gensym "KEY-VALS-"))
)

    `(defun ,name (request)
       (destructuring-bind (,request-path &optional ,request-query)
           (split-sequence:split-sequence #\? (request-uri request))
         (multiple-value-bind (,m0 ,m1 ,rn0 ,rn1)
             (cl-ppcre:scan ,regex ,request-path)
           (declare (ignore ,m1))
           (when ,m0
             (let ((,key-vals (mapcan #'(lambda (k=v)
                                          (destructuring-bind (key &optional (val t))
                                              (split-sequence:split-sequence #\= k=v)
                                            (list (intern (string-upcase key) (find-package '#:keyword))
                                                  val
)
)
)

                                      (split-sequence:split-sequence #\& ,request-query)
)
)
)

               (declare (ignorable ,key-vals))
               (lambda ()
                 (let (,@(loop for i from 0
                            for arg in named collecting
                            `(,arg (when (aref ,rn0 ,i)
                                     (subseq ,request-path (aref ,rn0 ,i) (aref ,rn1 ,i))
)
)
)

                       (keys ,key-vals)
                         ,@(loop for key in keys collecting
                                `(,key (getf ,key-vals
                                             (intern (symbol-name ',key)
                                                     (find-package '#:keyword)
)
)
)
)
)

                   ,@forms
)
)
)
)
)
)
)
)
)



;;eg. like this

(define-handler picpage (id dash title &key one three five) "/picpage/(\\d+)(-([^/?]+))?"
  (declare (optimize (debug 3)))
  (declare (ignore dash))
  (with-template (title)
    (:p (esc (format nil "If this works, i'll be shocked. id is ~a; title is ~a; one is ~a; three is ~a; five is ~a" id title one three five)))
    (:p (esc (format nil "keys ~s; key one: ~s" keys (getf keys 'one))))
)
)

This paste has no annotations.

Colorize as:
Show Line Numbers

Ads absolutely not by Google

Lisppaste pastes can be made by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively.