(defpackage #:weekend.client.dexador (:use #:cl) (:import-from #:flatbind #:do>) (:local-nicknames (#:wknd #:weekend) (#:a #:alexandria-2)) (:export #:generate)) (in-package #:weekend.client.dexador) (defun generate-client-for (class) (when (symbolp class) (setf class (find-class class))) (let* ((args (mapcar (a:compose #'intern #'string) (wknd:class-initargs class))) (parts (loop :for part :in (wknd:route-builder-parts class) :when (or (stringp part) (characterp part)) :collect part :else :collect (intern (string part)))) (method (wknd:request-method class)) (dexador-fn (ecase method (:get 'dexador:get) (:post 'dexador:post) (:put 'dexador:put) (:delete 'dexador:delete) (:patch 'dexador:patch) (:head 'dexador:head))) (reqbody (when (wknd:body-expected-p method) `(mapcar #'cons ',(mapcar #'string (wknd:class-initargs class)) (list ,@args)))) (host (loop :with var := "HOST" :while (find var args :test #'string-equal) :do (setf var (concatenate 'string var "%")) :finally (return (intern var)))) (dexador-kwargs (loop :with var := "DEXADOR-KWARGS" :while (find var args :test #'string-equal) :do (setf var (concatenate 'string var "%")) :finally (return (intern var))))) `(defun ,(class-name class) (,host ,@args &rest ,dexador-kwargs) (apply #',dexador-fn (concatenate 'string ,host ,@parts) ,@(when reqbody (list :content reqbody)) ,dexador-kwargs)))) (defun generate (class) (eval (generate-client-for class)))