summaryrefslogtreecommitdiff
path: root/src/serializing.lisp
diff options
context:
space:
mode:
authorGravatar Uko Kokņevičs2025-10-13 05:21:41 +0300
committerGravatar Uko Kokņevičs2025-10-13 05:21:41 +0300
commit191a27fd142af7a14ca6ad1abcd293f09e63f6ad (patch)
tree24f7384a9da0bf2d46dd38c9668f1e49ba1866ca /src/serializing.lisp
parentOupsie (diff)
downloadukkoclot-191a27fd142af7a14ca6ad1abcd293f09e63f6ad.tar.gz
ukkoclot-191a27fd142af7a14ca6ad1abcd293f09e63f6ad.tar.xz
ukkoclot-191a27fd142af7a14ca6ad1abcd293f09e63f6ad.zip
Move serializing stuff from bot/impl to a new file
Diffstat (limited to '')
-rw-r--r--src/serializing.lisp68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/serializing.lisp b/src/serializing.lisp
new file mode 100644
index 0000000..7fafb3a
--- /dev/null
+++ b/src/serializing.lisp
@@ -0,0 +1,68 @@
1;; SPDX-License-Identifier: EUPL-1.2
2;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com>
3(defpackage :ukkoclot/serializing
4 (:use :c2cl :iterate)
5 (:import-from :log)
6 (:import-from :ukkoclot/strings :lisp->snake-case)
7 (:local-nicknames
8 (:jzon :com.inuoe.jzon))
9 (:export :fixup-args :fixup-value :parse-value :try-parse-value))
10(in-package :ukkoclot/serializing)
11
12(defun fixup-args (args)
13 (iter (for (key . value) in args)
14 (collect
15 (cons (string-downcase (lisp->snake-case (symbol-name key)))
16 (fixup-value value)))))
17
18(defgeneric fixup-value (value)
19 (:documentation "Fixup outgoing *top-level* `value' before passing it to telegram.")
20 (:method (value)
21 (jzon:stringify value :pretty *print-pretty*))
22 (:method ((value null))
23 value)
24 (:method ((value number))
25 value)
26 (:method ((value pathname))
27 value)
28 (:method ((value string))
29 value))
30
31(defgeneric parse-value (type json)
32 (:documentation "Parse incoming value of `type' from the parsed `json'.")
33 (:method (type json)
34 (log:error "I don't know how to parse simple type ~A!" type)
35 (error "I don't know how to parse simple type ~A!" type))
36 (:method ((type (eql 'boolean)) json)
37 (check-type json boolean)
38 json)
39 (:method ((type (eql 'integer)) json)
40 (check-type json integer)
41 json)
42 (:method ((type (eql 'null)) json)
43 (check-type json null)
44 json)
45 (:method ((type (eql 'string)) json)
46 (check-type json string)
47 json))
48
49(defmethod parse-value ((type cons) json)
50 (cond ((and (eq (car type) 'array)
51 (null (cddr type)))
52 (when json
53 (let ((element-type (cadr type)))
54 (iter (for element in-vector json)
55 (collect (parse-value element-type element) result-type vector)))))
56 ((eq (car type) 'or)
57 (iter (for el-type in (cdr type))
58 (multiple-value-bind (success res) (try-parse-value el-type json)
59 (when success
60 (return res)))
61 (finally
62 (error "Failed to parse ~S as ~A!" json type))))
63 (t
64 (error "I don't know how to parse complex type ~A!" type))))
65
66(defun try-parse-value (type json)
67 (handler-case (values t (parse-value type json))
68 (error () (values nil nil))))