summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Okay <okay@toyful.space>2022-02-14 09:56:22 -0600
committerColin Okay <okay@toyful.space>2022-02-14 09:56:22 -0600
commit22a1c72874e579858d6add4f2b617495acc7cd4d (patch)
tree50214ae7b1b4dc599758ea95b3e0583d7c3a0227
parenta9930479cf91e463e1bf2d412712e7bf46c74326 (diff)
client system generation v0.1.0
-rw-r--r--clpmfile.lock2
-rw-r--r--hacking.lisp2
-rw-r--r--lazybones-client.lisp88
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)