From 2920126da9ef46424d32784412d980772f5d8369 Mon Sep 17 00:00:00 2001 From: Colin Okay Date: Thu, 3 Feb 2022 17:27:26 -0600 Subject: hacking on lazybones reboot --- clpmfile.lock | 21 ++++++++++++++++++-- lazybones.asd | 2 +- lazybones.lisp | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- package.lisp | 4 +++- 4 files changed, 83 insertions(+), 6 deletions(-) diff --git a/clpmfile.lock b/clpmfile.lock index 2e8209f..4baaf5d 100644 --- a/clpmfile.lock +++ b/clpmfile.lock @@ -35,8 +35,13 @@ ("chunga" :version "2020-04-27" :source "quicklisp" :systems ("chunga")) ("cl+ssl" :version "2021-12-30" :source "quicklisp" :systems ("cl+ssl")) ("cl-base64" :version "2020-10-16" :source "quicklisp" :systems ("cl-base64")) +("cl-change-case" :version "2021-04-11" :source "quicklisp" :systems + ("cl-change-case")) ("cl-fad" :version "2021-01-24" :source "quicklisp" :systems ("cl-fad")) -("cl-ppcre" :version "2019-05-21" :source "quicklisp" :systems ("cl-ppcre")) +("cl-ppcre" :version "2019-05-21" :source "quicklisp" :systems + ("cl-ppcre" "cl-ppcre-unicode")) +("cl-str" :version "2021-05-31" :source "quicklisp" :systems ("str")) +("cl-unicode" :version "2021-02-28" :source "quicklisp" :systems ("cl-unicode")) ("flexi-streams" :version "2021-08-07" :source "quicklisp" :systems ("flexi-streams")) ("hunchentoot" :version "2020-06-10" :source "quicklisp" :systems @@ -85,9 +90,21 @@ ("cl-base64" ((:system :name "hunchentoot") (:system :name "cl-base64"))) +("cl-change-case" ((:system :name "str") (:system :name "cl-change-case"))) + ("cl-fad" ((:system :name "hunchentoot") (:system :name "cl-fad"))) -("cl-ppcre" ((:system :name "hunchentoot") (:system :name "cl-ppcre"))) +("cl-ppcre" ((:system :name "str") (:system :name "cl-ppcre")) + ((:system :name "str") (:system :name "cl-ppcre-unicode")) + ((:system :name "hunchentoot") (:system :name "cl-ppcre")) + ((:system :name "cl-unicode") (:system :name "cl-ppcre")) + ((:system :name "cl-ppcre-unicode") (:system :name "cl-ppcre")) + ((:system :name "cl-change-case") (:system :name "cl-ppcre")) + ((:system :name "cl-change-case") (:system :name "cl-ppcre-unicode"))) + +("cl-str" ((:system :name "lazybones") (:system :name "str"))) + +("cl-unicode" ((:system :name "cl-ppcre-unicode") (:system :name "cl-unicode"))) ("flexi-streams" ((:system :name "hunchentoot") (:system :name "flexi-streams")) diff --git a/lazybones.asd b/lazybones.asd index 8dacff1..389dafd 100644 --- a/lazybones.asd +++ b/lazybones.asd @@ -6,6 +6,6 @@ :license "AGPLv3" :version "0.2.0" :serial t - :depends-on (#:hunchentoot #:alexandria) + :depends-on (#:hunchentoot #:alexandria #:str) :components ((:file "package") (:file "lazybones"))) diff --git a/lazybones.lisp b/lazybones.lisp index 82e5fff..6e1da32 100644 --- a/lazybones.lisp +++ b/lazybones.lisp @@ -2,6 +2,9 @@ (in-package #:lazybones) +(defgeneric handle-request (what request) + (:documentation "Implemented for APP and ENDPOINT instances.")) + (defclass app () ((name :reader app-name @@ -12,7 +15,7 @@ :reader app-version :initarg :vsn :initarg :version :initform "0.0.1" - :type string) + :type string) (root :reader app-root :initarg :root @@ -31,8 +34,63 @@ :accessor app-routes :initform nil))) +(defgeneric dispatch-handler-p (endpoint request) + (:documentation "T if ENDPOINT should handle REQUEST, NIL otherwise")) + +(defclass endpoint () + ((method :reader endpoint-method :initarg :method :initform :get) + (template :reader endpoint-template :initarg :template :initform (error "endpoint template required")) + (dispatch-pattern :reader endpoint-dispatch-pattern) + (handler-function :reader endpoint-request-handler) + (documentation :reader endpoint-documentation :initarg :doc :initform ""))) + + +(defparameter +http-methods+ + (list :get :head :put :post :delete :patch)) + (defun parse-route-string-template (template) - ) + "Routes are of the form + +/foo/bar/<>/blah + +/foo/bar/<>/blah + +On success returns things like: + +(\"foo\" \"bar\" (VARIABLE) \"blah\") +(\"foo\" \"bar\" (VAR PARSE-INTEGER) \"blah\") + +Returns NIL on failure" + (when (stringp template) + (cond ((equal "" template) nil) + (t + (loop for field in (str:split #\/ template) + for var? = (parse-route-variable-string field) + when var? + collect var? + else + collect (string-downcase field)))))) + +(defun parse-route-variable-string (string) + "A route variable string looks like <> or <> + +In the case of a successful parse, a list of one or two symbols is +returned. These symbosl are created using read-from-string, which +allows for these symbols' packages to be specified if desired. + +Returns NIL on failre." + (when (and (a:starts-with-subseq "<<" string) + (a:ends-with-subseq ">>" string)) + (destructuring-bind + (var-name . decoder?) + (re:split " +" + (string-trim " " (subseq string 2 (- (length string) 2)))) + (if decoder? + (list (read-from-string var-name) (read-from-string (first decoder?))) + (list (read-from-string var-name)))))) (defun add-route (method routestring handler-function) + (assert (member method +http-methods+) nil + "~a is not a valid HTTP method indicator." + method) ) diff --git a/package.lisp b/package.lisp index cd1720f..3dd7595 100644 --- a/package.lisp +++ b/package.lisp @@ -1,7 +1,9 @@ ;;;; package.lisp (defpackage #:lazybones - (:use #:cl)) + (:use #:cl) + (:local-nicknames (#:a #:alexandria) + (#:re #:cl-ppcre-asd ))) ;; (defpackage #:lazybones.decoders ;; (:use #:cl) -- cgit v1.2.3