diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/hash-tables.lisp | 2 | ||||
| -rw-r--r-- | src/main.lisp | 14 | ||||
| -rw-r--r-- | src/serializing.lisp | 6 | ||||
| -rw-r--r-- | src/strings.lisp | 55 | ||||
| -rw-r--r-- | src/tg/method-macros.lisp | 6 | ||||
| -rw-r--r-- | src/tg/type-macros.lisp | 4 |
6 files changed, 25 insertions, 62 deletions
diff --git a/src/hash-tables.lisp b/src/hash-tables.lisp index d3b66dd..84ffbfe 100644 --- a/src/hash-tables.lisp +++ b/src/hash-tables.lisp | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | ;; SPDX-License-Identifier: EUPL-1.2 | 1 | ;; SPDX-License-Identifier: EUPL-1.2 |
| 2 | ;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com> | 2 | ;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com> |
| 3 | (defpackage :ukkoclot/hash-tables | 3 | (defpackage :ukkoclot/hash-tables |
| 4 | (:documentation "Utilities for dealing with hash tables.") | 4 | (:documentation "Hash-table-oriented utilities.") |
| 5 | (:use :c2cl) | 5 | (:use :c2cl) |
| 6 | (:import-from :alexandria :with-gensyms) | 6 | (:import-from :alexandria :with-gensyms) |
| 7 | (:export :alist->hash-table :gethash-lazy :plist->hash-table)) | 7 | (:export :alist->hash-table :gethash-lazy :plist->hash-table)) |
diff --git a/src/main.lisp b/src/main.lisp index 28c3801..5d3cf76 100644 --- a/src/main.lisp +++ b/src/main.lisp | |||
| @@ -7,11 +7,11 @@ | |||
| 7 | (:import-from :com.dieggsy.f-string :enable-f-strings) | 7 | (:import-from :com.dieggsy.f-string :enable-f-strings) |
| 8 | (:import-from :log) | 8 | (:import-from :log) |
| 9 | (:import-from :serapeum :drop) | 9 | (:import-from :serapeum :drop) |
| 10 | (:import-from :str) | ||
| 10 | (:import-from :ukkoclot/db :with-db) | 11 | (:import-from :ukkoclot/db :with-db) |
| 11 | (:import-from :ukkoclot/serializing :fixup-value) | 12 | (:import-from :ukkoclot/serializing :fixup-value) |
| 12 | (:import-from :ukkoclot/state :make-bot :bot-config :bot-power-on) | 13 | (:import-from :ukkoclot/state :make-bot :bot-config :bot-power-on) |
| 13 | (:import-from :ukkoclot/strings | 14 | (:import-from :ukkoclot/strings :escape-xml :is-tg-whitespace :is-tg-whitespace-str) |
| 14 | :escape-xml :is-tg-whitespace :is-tg-whitespace-str :starts-with :starts-with-ignore-case) | ||
| 15 | (:local-nicknames | 15 | (:local-nicknames |
| 16 | (:jzon :com.inuoe.jzon)) | 16 | (:jzon :com.inuoe.jzon)) |
| 17 | (:export :main)) | 17 | (:export :main)) |
| @@ -70,7 +70,7 @@ | |||
| 70 | (defun on-callback-query (bot cb) | 70 | (defun on-callback-query (bot cb) |
| 71 | (let ((data (callback-query-data cb))) | 71 | (let ((data (callback-query-data cb))) |
| 72 | (cond ((and data | 72 | (cond ((and data |
| 73 | (starts-with data "bbl:") | 73 | (str:starts-with-p "bbl:" data :ignore-case nil) |
| 74 | (= (user-id (callback-query-from cb)) | 74 | (= (user-id (callback-query-from cb)) |
| 75 | (config-owner (bot-config bot)))) | 75 | (config-owner (bot-config bot)))) |
| 76 | (let ((bot-id (read-from-string data t nil :start 4))) | 76 | (let ((bot-id (read-from-string data t nil :start 4))) |
| @@ -83,7 +83,7 @@ | |||
| 83 | :callback-query-id (callback-query-id cb) | 83 | :callback-query-id (callback-query-id cb) |
| 84 | :text "OK")) | 84 | :text "OK")) |
| 85 | ((and data | 85 | ((and data |
| 86 | (starts-with data "bwl:") | 86 | (str:starts-with-p "bwl:" data :ignore-case nil) |
| 87 | (= (user-id (callback-query-from cb)) | 87 | (= (user-id (callback-query-from cb)) |
| 88 | (config-owner (bot-config bot)))) | 88 | (config-owner (bot-config bot)))) |
| 89 | (let ((bot-id (read-from-string data t nil :start 4))) | 89 | (let ((bot-id (read-from-string data t nil :start 4))) |
| @@ -161,7 +161,7 @@ | |||
| 161 | ((equal text ">:3") | 161 | ((equal text ">:3") |
| 162 | (reply-message bot msg "<b>>:3</b>" :parse-mode html)) | 162 | (reply-message bot msg "<b>>:3</b>" :parse-mode html)) |
| 163 | 163 | ||
| 164 | ((starts-with-ignore-case text "big ") | 164 | ((str:starts-with-p "big " text) |
| 165 | (let ((the-text (drop 4 text))) | 165 | (let ((the-text (drop 4 text))) |
| 166 | (unless (is-tg-whitespace-str the-text) | 166 | (unless (is-tg-whitespace-str the-text) |
| 167 | (reply-message bot msg | 167 | (reply-message bot msg |
| @@ -190,12 +190,12 @@ | |||
| 190 | (or (message-reply-to-message msg) msg) | 190 | (or (message-reply-to-message msg) msg) |
| 191 | "dio cane")) | 191 | "dio cane")) |
| 192 | 192 | ||
| 193 | ((starts-with-ignore-case text "say ") | 193 | ((str:starts-with-p "say " text) |
| 194 | (let ((the-text (drop 4 text))) | 194 | (let ((the-text (drop 4 text))) |
| 195 | (unless (is-tg-whitespace-str the-text) | 195 | (unless (is-tg-whitespace-str the-text) |
| 196 | (reply-message bot msg the-text)))) | 196 | (reply-message bot msg the-text)))) |
| 197 | 197 | ||
| 198 | ((starts-with-ignore-case text "tiny ") | 198 | ((str:starts-with-p "tiny " text) |
| 199 | (let ((the-text (drop 5 text))) | 199 | (let ((the-text (drop 5 text))) |
| 200 | (unless (is-tg-whitespace-str the-text) | 200 | (unless (is-tg-whitespace-str the-text) |
| 201 | (reply-message bot msg | 201 | (reply-message bot msg |
diff --git a/src/serializing.lisp b/src/serializing.lisp index 205190f..71b0fb2 100644 --- a/src/serializing.lisp +++ b/src/serializing.lisp | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | (defpackage :ukkoclot/serializing | 3 | (defpackage :ukkoclot/serializing |
| 4 | (:use :c2cl :iterate) | 4 | (:use :c2cl :iterate) |
| 5 | (:import-from :log) | 5 | (:import-from :log) |
| 6 | (:import-from :ukkoclot/strings :lisp->snake-case) | 6 | (:import-from :str) |
| 7 | (:local-nicknames | 7 | (:local-nicknames |
| 8 | (:jzon :com.inuoe.jzon)) | 8 | (:jzon :com.inuoe.jzon)) |
| 9 | (:export :fixup-args :fixup-value :parse-value :try-parse-value)) | 9 | (:export :fixup-args :fixup-value :parse-value :try-parse-value)) |
| @@ -11,9 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | (defun fixup-args (args) | 12 | (defun fixup-args (args) |
| 13 | (iter (for (key . value) in args) | 13 | (iter (for (key . value) in args) |
| 14 | (collect | 14 | (collect (cons (str:snake-case key) (fixup-value value))))) |
| 15 | (cons (string-downcase (lisp->snake-case (symbol-name key))) | ||
| 16 | (fixup-value value))))) | ||
| 17 | 15 | ||
| 18 | (defgeneric fixup-value (value) | 16 | (defgeneric fixup-value (value) |
| 19 | (:documentation "Fixup outgoing *top-level* `value' before passing it to telegram.") | 17 | (:documentation "Fixup outgoing *top-level* `value' before passing it to telegram.") |
diff --git a/src/strings.lisp b/src/strings.lisp index b1b4f00..eae8ec0 100644 --- a/src/strings.lisp +++ b/src/strings.lisp | |||
| @@ -1,33 +1,30 @@ | |||
| 1 | ;; SPDX-License-Identifier: EUPL-1.2 | 1 | ;; SPDX-License-Identifier: EUPL-1.2 |
| 2 | ;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com> | 2 | ;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com> |
| 3 | (defpackage :ukkoclot/strings | 3 | (defpackage :ukkoclot/strings |
| 4 | (:documentation "String-oriented utilities.") | ||
| 4 | (:use :c2cl :iterate) | 5 | (:use :c2cl :iterate) |
| 5 | (:import-from :cl-unicode :general-category) | 6 | (:import-from :cl-unicode :general-category) |
| 6 | (:export | 7 | (:export |
| 7 | :ends-with | ||
| 8 | :escape-xml | 8 | :escape-xml |
| 9 | :is-tg-whitespace | 9 | :is-tg-whitespace |
| 10 | :is-tg-whitespace-str | 10 | :is-tg-whitespace-str)) |
| 11 | :lisp->camel-case | ||
| 12 | :lisp->snake-case | ||
| 13 | :snake->lisp-case | ||
| 14 | :starts-with | ||
| 15 | :starts-with-ignore-case)) | ||
| 16 | (in-package :ukkoclot/strings) | 11 | (in-package :ukkoclot/strings) |
| 17 | 12 | ||
| 18 | ;; These are very inefficient but I don't care until I profile | 13 | ;; These are very inefficient but I don't care until I profile |
| 19 | 14 | ||
| 20 | (defun ends-with (str suffix) | ||
| 21 | (and (> (length str) (length suffix)) | ||
| 22 | (string= str suffix :start1 (- (length str) (length suffix))))) | ||
| 23 | |||
| 24 | (defun escape-xml (str &optional out) | 15 | (defun escape-xml (str &optional out) |
| 16 | "Escape special XML characters in the STR. | ||
| 17 | |||
| 18 | OUT is the output stream or `nil' for outputting to a string." | ||
| 25 | (if out | 19 | (if out |
| 26 | (escape-xml% str out) | 20 | (escape-xml% str out) |
| 27 | (with-output-to-string (out) | 21 | (with-output-to-string (out) |
| 28 | (escape-xml% str out)))) | 22 | (escape-xml% str out)))) |
| 29 | 23 | ||
| 30 | (defun escape-xml% (str out) | 24 | (defun escape-xml% (str out) |
| 25 | "See `escape-xml'. | ||
| 26 | |||
| 27 | OUT is always the stream." | ||
| 31 | (loop for ch across str do | 28 | (loop for ch across str do |
| 32 | (case ch | 29 | (case ch |
| 33 | (#\< (write-string "<" out)) | 30 | (#\< (write-string "<" out)) |
| @@ -37,6 +34,7 @@ | |||
| 37 | (otherwise (write-char ch out))))) | 34 | (otherwise (write-char ch out))))) |
| 38 | 35 | ||
| 39 | (defun is-tg-whitespace (ch) | 36 | (defun is-tg-whitespace (ch) |
| 37 | "Checks if CH on its own would be considered whitespace by telegram." | ||
| 40 | (let ((gc (general-category ch))) | 38 | (let ((gc (general-category ch))) |
| 41 | (or (string= gc "Zs") ; Separator, space | 39 | (or (string= gc "Zs") ; Separator, space |
| 42 | (string= gc "Zl") ; Separator, line | 40 | (string= gc "Zl") ; Separator, line |
| @@ -45,39 +43,6 @@ | |||
| 45 | (= (char-code ch) #x2800)))) ; BRAILLE PATTERN BLANK | 43 | (= (char-code ch) #x2800)))) ; BRAILLE PATTERN BLANK |
| 46 | 44 | ||
| 47 | (defun is-tg-whitespace-str (str) | 45 | (defun is-tg-whitespace-str (str) |
| 46 | "Checks if message containing just STR would be considered whitespace by telegram." | ||
| 48 | (iter (for ch in-string str) | 47 | (iter (for ch in-string str) |
| 49 | (always (is-tg-whitespace ch)))) | 48 | (always (is-tg-whitespace ch)))) |
| 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 | |||
| 63 | (defun lisp->snake-case (str) | ||
| 64 | (with-output-to-string (out) | ||
| 65 | (loop for ch across str do | ||
| 66 | (case ch | ||
| 67 | (#\- (write-char #\_ out)) | ||
| 68 | (otherwise (write-char ch out)))))) | ||
| 69 | |||
| 70 | (defun snake->lisp-case (str) | ||
| 71 | (with-output-to-string (out) | ||
| 72 | (loop for ch across str do | ||
| 73 | (case ch | ||
| 74 | (#\_ (write-char #\- out)) | ||
| 75 | (otherwise (write-char ch out)))))) | ||
| 76 | |||
| 77 | (defun starts-with (str prefix) | ||
| 78 | (and (> (length str) (length prefix)) | ||
| 79 | (string= str prefix :end1 (length prefix)))) | ||
| 80 | |||
| 81 | (defun starts-with-ignore-case (str prefix) | ||
| 82 | (and (> (length str) (length prefix)) | ||
| 83 | (string-equal str prefix :end1 (length prefix)))) | ||
diff --git a/src/tg/method-macros.lisp b/src/tg/method-macros.lisp index b924e15..0be6f00 100644 --- a/src/tg/method-macros.lisp +++ b/src/tg/method-macros.lisp | |||
| @@ -6,8 +6,8 @@ | |||
| 6 | (:import-from :alexandria :with-gensyms) | 6 | (:import-from :alexandria :with-gensyms) |
| 7 | (:import-from :com.dieggsy.f-string :enable-f-strings) | 7 | (:import-from :com.dieggsy.f-string :enable-f-strings) |
| 8 | (:import-from :serapeum :take) | 8 | (:import-from :serapeum :take) |
| 9 | (:import-from :str) | ||
| 9 | (:import-from :ukkoclot/state :bot) | 10 | (:import-from :ukkoclot/state :bot) |
| 10 | (:import-from :ukkoclot/strings :ends-with :lisp->camel-case) | ||
| 11 | (:import-from :ukkoclot/transport :do-call) | 11 | (:import-from :ukkoclot/transport :do-call) |
| 12 | (:export :define-tg-method)) | 12 | (:export :define-tg-method)) |
| 13 | (in-package :ukkoclot/tg/method-macros) | 13 | (in-package :ukkoclot/tg/method-macros) |
| @@ -36,8 +36,8 @@ | |||
| 36 | (collect (apply #'make-param param-spec)))) | 36 | (collect (apply #'make-param param-spec)))) |
| 37 | 37 | ||
| 38 | (defun path-from-name (name) | 38 | (defun path-from-name (name) |
| 39 | (let ((str (lisp->camel-case (symbol-name name)))) | 39 | (let ((str (str:camel-case name))) |
| 40 | (if (ends-with str "%") | 40 | (if (str:ends-with-p "%" str :ignore-case nil) |
| 41 | (take (- (length str) 1) str) | 41 | (take (- (length str) 1) str) |
| 42 | str))) | 42 | str))) |
| 43 | 43 | ||
diff --git a/src/tg/type-macros.lisp b/src/tg/type-macros.lisp index 5f99cba..75afab0 100644 --- a/src/tg/type-macros.lisp +++ b/src/tg/type-macros.lisp | |||
| @@ -5,9 +5,9 @@ | |||
| 5 | (:use :c2cl :iterate) | 5 | (:use :c2cl :iterate) |
| 6 | (:import-from :alexandria :with-gensyms) | 6 | (:import-from :alexandria :with-gensyms) |
| 7 | (:import-from :com.dieggsy.f-string :enable-f-strings) | 7 | (:import-from :com.dieggsy.f-string :enable-f-strings) |
| 8 | (:import-from :str) | ||
| 8 | (:import-from :ukkoclot/serializing :parse-value) | 9 | (:import-from :ukkoclot/serializing :parse-value) |
| 9 | (:import-from :ukkoclot/hash-tables :gethash-lazy) | 10 | (:import-from :ukkoclot/hash-tables :gethash-lazy) |
| 10 | (:import-from :ukkoclot/strings :lisp->snake-case) | ||
| 11 | (:local-nicknames | 11 | (:local-nicknames |
| 12 | (:jzon :com.inuoe.jzon)) | 12 | (:jzon :com.inuoe.jzon)) |
| 13 | (:export :define-tg-type)) | 13 | (:export :define-tg-type)) |
| @@ -39,7 +39,7 @@ | |||
| 39 | (intern (concatenate 'string (symbol-name name) "-" (symbol-name (field-name field))))) | 39 | (intern (concatenate 'string (symbol-name name) "-" (symbol-name (field-name field))))) |
| 40 | 40 | ||
| 41 | (defun field-hash-key (field) | 41 | (defun field-hash-key (field) |
| 42 | (string-downcase (lisp->snake-case (symbol-name (field-name field))))) | 42 | (str:snake-case (field-name field))) |
| 43 | 43 | ||
| 44 | (defun field-keyword (field) | 44 | (defun field-keyword (field) |
| 45 | (intern (symbol-name (field-name field)) :keyword)) | 45 | (intern (symbol-name (field-name field)) :keyword)) |