summaryrefslogtreecommitdiff
path: root/src/bot/method-macros.lisp
diff options
context:
space:
mode:
authorGravatar Uko Kokņevičs2025-10-13 00:26:15 +0300
committerGravatar Uko Kokņevičs2025-10-13 00:26:15 +0300
commit0749b67b29db8773e840345cc67963a1c1545cba (patch)
tree49dbd89b310645ec081cdad8632d8a45ebbb79e4 /src/bot/method-macros.lisp
parentRename tg-types to just tg (diff)
downloadukkoclot-0749b67b29db8773e840345cc67963a1c1545cba.tar.gz
ukkoclot-0749b67b29db8773e840345cc67963a1c1545cba.tar.xz
ukkoclot-0749b67b29db8773e840345cc67963a1c1545cba.zip
Move define-tg-method to a new file
Diffstat (limited to 'src/bot/method-macros.lisp')
-rw-r--r--src/bot/method-macros.lisp64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/bot/method-macros.lisp b/src/bot/method-macros.lisp
new file mode 100644
index 0000000..7b54dc9
--- /dev/null
+++ b/src/bot/method-macros.lisp
@@ -0,0 +1,64 @@
1;; SPDX-License-Identifier: EUPL-1.2
2;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com>
3(defpackage :ukkoclot/bot/method-macros
4 (:use :c2cl :iterate :ukkoclot/bot/impl)
5 (:export :define-tg-method))
6(in-package :ukkoclot/bot/method-macros)
7
8(eval-when (:compile-toplevel :load-toplevel :execute)
9 (defstruct (param (:constructor make-param%)) name type default skip-if-default)
10
11 (defparameter +unique+ (gensym))
12
13 (defun make-param (name type &optional (default +unique+) &key (skip-if-default (not (eq default +unique+))))
14 (let ((default (if (eq default +unique+)
15 `(error ,(format nil "No value given for ~A" name))
16 default)))
17 (make-param% :name name
18 :type type
19 :default default
20 :skip-if-default skip-if-default)))
21
22 (defun parse-param-specs (param-specs)
23 (iter (for param-spec in param-specs)
24 (collect (apply #'make-param param-spec))))
25
26 (defun emit-append-to-args (param args)
27 `(setf ,args (acons ',(param-name param) ,(param-name param) ,args)))
28
29 (defun emit-arg-type (param)
30 `(,(intern (symbol-name (param-name param)) :keyword)
31 ,(param-type param)))
32
33 (defun emit-defun-arg (param)
34 `(,(param-name param) ,(param-default param)))
35
36 (defun emit-defun (name return-type params method path)
37 (let ((revparams (reverse params))
38 (args (gensym "ARGS"))
39 (bot (gensym "BOT")))
40 `(defun ,name (,bot &key ,@(iter (for param in params)
41 (collect (emit-defun-arg param))))
42 (let (,args)
43 ,@(iter (for param in revparams)
44 (collect (if (param-skip-if-default param)
45 `(unless (equal ,(param-name param)
46 ,(param-default param))
47 ,(emit-append-to-args param args))
48 (emit-append-to-args param args))))
49 (do-call ,bot ,method ,path ',return-type ,args)))))
50
51 (defun emit-ftype (name return-type params)
52 `(declaim (ftype (function (bot &key ,@(iter (for param in params)
53 (collect (emit-arg-type param))))
54 ,return-type)
55 ,name))))
56
57;; TODO: Automatically derive path from name
58(defmacro define-tg-method (
59 (name type path &optional (method :POST))
60 &body param-specs)
61 (let ((params (parse-param-specs param-specs)))
62 `(progn
63 ,(emit-ftype name type params)
64 ,(emit-defun name type params method path))))