summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bot/method-macros.lisp16
-rw-r--r--src/bot/methods.lisp18
-rw-r--r--src/strings.lisp26
3 files changed, 45 insertions, 15 deletions
diff --git a/src/bot/method-macros.lisp b/src/bot/method-macros.lisp
index 0500de9..d4f04ad 100644
--- a/src/bot/method-macros.lisp
+++ b/src/bot/method-macros.lisp
@@ -3,6 +3,7 @@
3(defpackage :ukkoclot/bot/method-macros 3(defpackage :ukkoclot/bot/method-macros
4 (:use :c2cl :iterate) 4 (:use :c2cl :iterate)
5 (:import-from :ukkoclot/state :bot) 5 (:import-from :ukkoclot/state :bot)
6 (:import-from :ukkoclot/strings :ends-with :lisp->camel-case)
6 (:import-from :ukkoclot/transport :do-call) 7 (:import-from :ukkoclot/transport :do-call)
7 (:export :define-tg-method)) 8 (:export :define-tg-method))
8(in-package :ukkoclot/bot/method-macros) 9(in-package :ukkoclot/bot/method-macros)
@@ -25,6 +26,12 @@
25 (iter (for param-spec in param-specs) 26 (iter (for param-spec in param-specs)
26 (collect (apply #'make-param param-spec)))) 27 (collect (apply #'make-param param-spec))))
27 28
29 (defun path-from-name (name)
30 (let ((str (lisp->camel-case (symbol-name name))))
31 (if (ends-with str "%")
32 (subseq str 0 (- (length str) 1))
33 str)))
34
28 (defun emit-append-to-args (param args) 35 (defun emit-append-to-args (param args)
29 `(setf ,args (acons ',(param-name param) ,(param-name param) ,args))) 36 `(setf ,args (acons ',(param-name param) ,(param-name param) ,args)))
30 37
@@ -35,7 +42,7 @@
35 (defun emit-defun-arg (param) 42 (defun emit-defun-arg (param)
36 `(,(param-name param) ,(param-default param))) 43 `(,(param-name param) ,(param-default param)))
37 44
38 (defun emit-defun (name return-type params method path) 45 (defun emit-defun (name return-type params method)
39 (let ((revparams (reverse params)) 46 (let ((revparams (reverse params))
40 (args (gensym "ARGS")) 47 (args (gensym "ARGS"))
41 (bot (gensym "BOT"))) 48 (bot (gensym "BOT")))
@@ -48,7 +55,7 @@
48 ,(param-default param)) 55 ,(param-default param))
49 ,(emit-append-to-args param args)) 56 ,(emit-append-to-args param args))
50 (emit-append-to-args param args)))) 57 (emit-append-to-args param args))))
51 (do-call ,bot ,method ,path ',return-type ,args))))) 58 (do-call ,bot ,method ,(path-from-name name) ',return-type ,args)))))
52 59
53 (defun emit-ftype (name return-type params) 60 (defun emit-ftype (name return-type params)
54 `(declaim (ftype (function (bot &key ,@(iter (for param in params) 61 `(declaim (ftype (function (bot &key ,@(iter (for param in params)
@@ -56,11 +63,10 @@
56 ,return-type) 63 ,return-type)
57 ,name)))) 64 ,name))))
58 65
59;; TODO: Automatically derive path from name
60(defmacro define-tg-method ( 66(defmacro define-tg-method (
61 (name type path &optional (method :POST)) 67 (name type &optional (method :POST))
62 &body param-specs) 68 &body param-specs)
63 (let ((params (parse-param-specs param-specs))) 69 (let ((params (parse-param-specs param-specs)))
64 `(progn 70 `(progn
65 ,(emit-ftype name type params) 71 ,(emit-ftype name type params)
66 ,(emit-defun name type params method path)))) 72 ,(emit-defun name type params method))))
diff --git a/src/bot/methods.lisp b/src/bot/methods.lisp
index 2daea6f..6f01cae 100644
--- a/src/bot/methods.lisp
+++ b/src/bot/methods.lisp
@@ -6,19 +6,19 @@
6 (:export :answer-callback-query :delete-message :send-animation :edit-message-text :get-me :get-updates :send-message :set-my-name)) 6 (:export :answer-callback-query :delete-message :send-animation :edit-message-text :get-me :get-updates :send-message :set-my-name))
7(in-package :ukkoclot/bot/methods) 7(in-package :ukkoclot/bot/methods)
8 8
9(define-tg-method (answer-callback-query boolean "answerCallbackQuery") 9(define-tg-method (answer-callback-query boolean)
10 (callback-query-id string) 10 (callback-query-id string)
11 (text (or string null) nil) 11 (text (or string null) nil)
12 (show-alert boolean nil) 12 (show-alert boolean nil)
13 (url (or string null) nil) 13 (url (or string null) nil)
14 (cache-time (or integer null) nil)) 14 (cache-time (or integer null) nil))
15 15
16(define-tg-method (delete-message boolean "deleteMessage") 16(define-tg-method (delete-message boolean)
17 (chat-id (or integer string)) 17 (chat-id (or integer string))
18 (message-id integer)) 18 (message-id integer))
19 19
20;; TODO: Add a way to simply specify :message msg :) 20;; TODO: Add a way to simply specify :message msg :)
21(define-tg-method (edit-message-text message "editMessageText") 21(define-tg-method (edit-message-text message)
22 (business-connection-id (or string null) nil) 22 (business-connection-id (or string null) nil)
23 (chat-id (or integer string null) nil) 23 (chat-id (or integer string null) nil)
24 (message-id (or integer null) nil) 24 (message-id (or integer null) nil)
@@ -29,7 +29,7 @@
29 (link-preview-options (or link-preview-options null) nil) 29 (link-preview-options (or link-preview-options null) nil)
30 (reply-markup (or inline-keyboard-markup null) nil)) 30 (reply-markup (or inline-keyboard-markup null) nil))
31 31
32(define-tg-method (get-me% user "getMe" :GET)) 32(define-tg-method (get-me% user :GET))
33 33
34(defun get-me (bot) 34(defun get-me (bot)
35 (let ((res (get-me% bot))) 35 (let ((res (get-me% bot)))
@@ -37,16 +37,16 @@
37 (setf (bot-username% bot) (user-username res)) 37 (setf (bot-username% bot) (user-username res))
38 res)) 38 res))
39 39
40(define-tg-method (get-my-name bot-name "getMyName" :GET) 40(define-tg-method (get-my-name bot-name :GET)
41 (language-code (or string null) nil)) 41 (language-code (or string null) nil))
42 42
43(define-tg-method (get-updates (array update) "getUpdates") 43(define-tg-method (get-updates (array update))
44 (offset (or integer null) nil) 44 (offset (or integer null) nil)
45 (limit (or integer null) nil) 45 (limit (or integer null) nil)
46 (timeout (or integer null) nil) 46 (timeout (or integer null) nil)
47 (allowed-updates (or string null) nil)) 47 (allowed-updates (or string null) nil))
48 48
49(define-tg-method (send-animation message "sendAnimation") 49(define-tg-method (send-animation message)
50 (business-connection-id (or string null) nil) 50 (business-connection-id (or string null) nil)
51 (chat-id (or integer string)) 51 (chat-id (or integer string))
52 (message-thread-id (or integer null) nil) 52 (message-thread-id (or integer null) nil)
@@ -69,7 +69,7 @@
69 (reply-parameters (or reply-parameters null) nil) 69 (reply-parameters (or reply-parameters null) nil)
70 (reply-markup (or inline-keyboard-markup reply-keyboard-markup reply-keyboard-remove force-reply null) nil)) 70 (reply-markup (or inline-keyboard-markup reply-keyboard-markup reply-keyboard-remove force-reply null) nil))
71 71
72(define-tg-method (send-message message "sendMessage") 72(define-tg-method (send-message message)
73 (business-connection-id (or string null) nil) 73 (business-connection-id (or string null) nil)
74 (chat-id (or integer string)) 74 (chat-id (or integer string))
75 (message-thread-id (or integer null) nil) 75 (message-thread-id (or integer null) nil)
@@ -83,7 +83,7 @@
83 (reply-parameters (or reply-parameters null) nil) 83 (reply-parameters (or reply-parameters null) nil)
84 (reply-markup (or inline-keyboard-markup reply-keyboard-markup reply-keyboard-remove force-reply null) nil)) 84 (reply-markup (or inline-keyboard-markup reply-keyboard-markup reply-keyboard-remove force-reply null) nil))
85 85
86(define-tg-method (set-my-name% boolean "setMyName") 86(define-tg-method (set-my-name% boolean)
87 (name (or string null) nil) 87 (name (or string null) nil)
88 (language-code (or string null) nil)) 88 (language-code (or string null) nil))
89 89
diff --git a/src/strings.lisp b/src/strings.lisp
index 68289aa..b11c31c 100644
--- a/src/strings.lisp
+++ b/src/strings.lisp
@@ -3,11 +3,23 @@
3(defpackage :ukkoclot/strings 3(defpackage :ukkoclot/strings
4 (:use :c2cl :iterate) 4 (:use :c2cl :iterate)
5 (:import-from :cl-unicode :general-category) 5 (:import-from :cl-unicode :general-category)
6 (:export :escape-xml :is-tg-whitespace-str :lisp->snake-case :snake->lisp-case :starts-with :starts-with-ignore-case)) 6 (:export
7 :ends-with
8 :escape-xml
9 :is-tg-whitespace-str
10 :lisp->camel-case
11 :lisp->snake-case
12 :snake->lisp-case
13 :starts-with
14 :starts-with-ignore-case))
7(in-package :ukkoclot/strings) 15(in-package :ukkoclot/strings)
8 16
9;; These are very inefficient but I don't care until I profile 17;; These are very inefficient but I don't care until I profile
10 18
19(defun ends-with (str suffix)
20 (and (> (length str) (length suffix))
21 (string= str suffix :start1 (- (length str) (length suffix)))))
22
11(defun escape-xml (str &optional out) 23(defun escape-xml (str &optional out)
12 (if out 24 (if out
13 (escape-xml% str out) 25 (escape-xml% str out)
@@ -36,6 +48,18 @@
36 (iter (for ch in-string str) 48 (iter (for ch in-string str)
37 (always (is-tg-whitespace ch)))) 49 (always (is-tg-whitespace ch))))
38 50
51(defun lisp->camel-case (str)
52 (with-output-to-string (out)
53 (let ((should-caps nil))
54 (iter (for ch in-string str)
55 (cond ((char= ch #\-)
56 (setf should-caps t))
57 (should-caps
58 (write-char (char-upcase ch) out)
59 (setf should-caps nil))
60 (t
61 (write-char (char-downcase ch) out)))))))
62
39(defun lisp->snake-case (str) 63(defun lisp->snake-case (str)
40 (with-output-to-string (out) 64 (with-output-to-string (out)
41 (loop for ch across str do 65 (loop for ch across str do