diff options
author | Colin Okay <okay@toyful.space> | 2022-02-14 09:56:22 -0600 |
---|---|---|
committer | Colin Okay <okay@toyful.space> | 2022-02-14 09:56:22 -0600 |
commit | 22a1c72874e579858d6add4f2b617495acc7cd4d (patch) | |
tree | 50214ae7b1b4dc599758ea95b3e0583d7c3a0227 | |
parent | a9930479cf91e463e1bf2d412712e7bf46c74326 (diff) |
client system generation v0.1.0
-rw-r--r-- | clpmfile.lock | 2 | ||||
-rw-r--r-- | hacking.lisp | 2 | ||||
-rw-r--r-- | lazybones-client.lisp | 88 |
3 files changed, 70 insertions, 22 deletions
diff --git a/clpmfile.lock b/clpmfile.lock index 94caf37..521b961 100644 --- a/clpmfile.lock +++ b/clpmfile.lock @@ -51,7 +51,7 @@ ("jonathan" :version "2020-09-25" :source "quicklisp" :systems ("jonathan")) ("lambda-riffs" :version (:commit "f7b3c081f2361f7370c80e7ff4a432241f34ce55") :source :implicit-vcs :systems ("lambda-riffs")) -("lazybones" :version (:commit "74eda585255b4a4d26cc783cecf2312a71370ed3") +("lazybones" :version (:commit "128f72863fa3f736c93175267beb23292e70e096") :source :implicit-vcs :systems ("lazybones")) ("lazybones-client.asd" :version :newest :source :implicit-file :systems ("lazybones-client")) diff --git a/hacking.lisp b/hacking.lisp index 2858157..f84054c 100644 --- a/hacking.lisp +++ b/hacking.lisp @@ -6,4 +6,4 @@ (lzb:defendpoint* :get "/search/:where parse-integer:" ((name identity) (age parse-integer)) () "This is documentation" - (lzb:http-ok (format nil "~a ~a ~a" where name age))) + (format nil "~a ~a ~a" where name age)) diff --git a/lazybones-client.lisp b/lazybones-client.lisp index 5fe1fea..7feb48c 100644 --- a/lazybones-client.lisp +++ b/lazybones-client.lisp @@ -2,8 +2,7 @@ (defpackage #:lazybones-client (:use #:cl) - (:export #:*host* - #:generate-client-system)) + (:export #:generate-client-system)) ;; dummy dexador package to keep lisp from complainging during code ;; generation @@ -13,8 +12,45 @@ (in-package :lazybones-client) -(defvar *host* nil - "The host to which the client will send its requests.") +(defparameter +preamble+ + "(defvar *host* nil + \"The host to which the client will send its requests.\") + + (defvar *body* nil + \"Body passed to client post, put, and patch requests\") + + (defvar *cookies* nil + \"An instance of CL-COOKIE:COOKIE-JAR.\" + + (defvar *headers* nil + \"A liist of (header-name . header-value) pairs.\") + + (defmacro request-with ((&key host body headers content-type cookies) &body forms) + \"Make a request in a specific context. + +HOST is a string, the hostname where the request will be sent. Defaults +to *HOST*. + +BODY should be a string, an alist, or a pathname. Default to *BODY* + +HEADERS should be an ALIST of (header-name . header-value) string +pairs. Defaults to *HEADERS*. + +CONTENT-TYPE is a convenience for supplying just the Content-Type +header. + +COOKIES should be an instance of CL-COOKIE:COOKIE-JAR. Defaults to +*COOKIES*. +\" + (let ((content-type-var (gensym))) + `(let ((*host* (or ,host *host*)) + (*body* (or ,body *body*)) + (*headers* (or ,headers *headers*)) + (*cookies* (or ,cookies *cookies*)) + (,content-type-var ,content-type)) + (when ,content-type-var + (push (cons \"Content-Type\" ,content-type-var) *headers*)) + ,@forms)))") (defun make-defun-name (method dispatch-pattern) "Utility for making function names for endpoint request functions." @@ -58,21 +94,30 @@ (lambda (x) (intern (symbol-name (first x)))) (lazybones::endpoint-params ep))) (dex-fn - (intern (symbol-name (lazybones::endpoint-method ep)) :dexador))) + (intern (symbol-name (lazybones::endpoint-method ep)) :dexador)) + (req-string + (gensym))) `(defun ,defun-name (,@vars ,@(when qparams (cons '&key qparams))) ,(lazybones::endpoint-documentation ep) - (,dex-fn (apply #'concatenate - 'string - lazybones-client::*host* - (format nil ,format-string ,@vars) - (when (or ,@qparams) - (list "?" ,@(params-to-query-string qparams)))))))) + (let ((,req-string + (apply #'concatenate + 'string + *host* + (format nil ,format-string ,@vars) + (when (or ,@qparams) + (list "?" ,@(params-to-query-string qparams)))))) + (if *body* + (,dex-fn ,req-string :content *body* :cookie-jar *cookies* :headers *headers*) + (,dex-fn ,req-string :cookie-jar *cookies* :headers *headers*)))))) (defun generate-client-functions-for-app (app) (loop for ep in (lazybones::app-endpoints app) collect (generate-client-function-for-endpoint ep))) +(defun all-function-names (app) + (mapcar 'endpoint-to-defun-name (lazybones::app-endpoints app))) + (defun app-client-package-name (app) (format nil "~a-CLIENT" (lazybones::app-name app))) @@ -81,7 +126,7 @@ (with-output-to-string (*standard-output*) (princ "(asdf:defsystem #:") (princ (app-client-package-name app)) (terpri) - (princ " :depends-on (#:lazybones-client)") + (princ " :depends-on (#:dexador)") (terpri) (princ " :components ((:file ") (princ #\") @@ -93,8 +138,10 @@ (with-output-to-string (out) (format out - "(defpackage :~a (:use :cl))" - (app-client-package-name app)) + "(defpackage :~a (:use :cl) +(:export #:*host* #:*body* #:*headers* #:*cookies* #:request-with~% ~{#:~a~^~%~}))" + (app-client-package-name app) + (all-function-names app)) (terpri out) (format out "(in-package :~a)" (app-client-package-name app)) (terpri out))) @@ -105,18 +152,19 @@ (defun client-lisp-file-name (app) (format nil "~a.lisp" (string-downcase (app-client-package-name app)))) - (defun generate-client-system (directory app) (assert (uiop:directory-exists-p directory)) (alexandria:write-string-into-file (generate-defsystem-for-client-of-app app) - (merge-pathnames (client-asd-file-name app) directory) - :if-exists :supersede) + (merge-pathnames (client-asd-file-name app) directory)) (alexandria:write-string-into-file (with-output-to-string (*standard-output*) (princ (generate-defpackage-for-client-of-app app)) - (terpri) + (princ #\newline) (princ #\newline) + (princ +preamble+) + (princ #\newline) (princ #\newline) (dolist (form (generate-client-functions-for-app app)) (print form) - (terpri))) - (merge-pathnames (client-lisp-file-name app) directory))) + (princ #\newline) (princ #\newline))) + (merge-pathnames (client-lisp-file-name app) directory)) + :ok) |