From 6249e0a8c5254e45cf79e3e53824e63e54e18233 Mon Sep 17 00:00:00 2001 From: Uko Kokņevičs Date: Sat, 18 Oct 2025 10:47:50 +0300 Subject: Make config be a global special variable --- src/config.lisp | 97 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 27 deletions(-) (limited to 'src/config.lisp') diff --git a/src/config.lisp b/src/config.lisp index 55575bb..03ded98 100644 --- a/src/config.lisp +++ b/src/config.lisp @@ -1,33 +1,76 @@ ;; SPDX-License-Identifier: EUPL-1.2 ;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs (defpackage :ukkoclot/config - (:use :c2cl :ukkoclot/hash-tables) - (:documentation - "Stuff for loading the configuration of the bot") + (:documentation "Stuff for loading the configuration of the bot") + (:nicknames :conf) + (:use :c2cl :iterate) (:export - :config-load :config-merge - :config-p - :config-bot-name :config-bot-token :config-db-path :config-dev-group :config-owner)) + #:*config* + #:config + #:make-config + #:config-p + #:copy-config + #:load-config + #:print-default + #:bot-name + #:bot-token + #:db-path + #:dev-group + #:owner)) (in-package :ukkoclot/config) -(defmacro defconfig (&rest slots-and-types) - "Macro to make the config struct creation easier." - `(defstruct config - ,@(loop for (name type) on slots-and-types by #'cddr - collect `(,(intern (symbol-name name)) (error "No value given for ~A" ,name) :type ,type :read-only t)))) - -(defconfig - :bot-name string - :bot-token string - :db-path string - :dev-group integer - :owner integer) - -(defun config-load (filename) - "Load the config from the given `filename'. All entries must be specified." - (apply #'make-config (with-open-file (f filename) (read f)))) - -(defun config-merge (config filename) - "Merge the current config with new entries from `filename'." - (loop for (name value) on (with-open-file (f filename) (read f)) by #'cddr do - (setf (slot-value config (intern (symbol-name name) :ukkoclot/config)) value))) +(defstruct config + (bot-name "Ukko's Clot" :type string) + (bot-token "123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi" :type string) + (db-path #P"./data.db" :type (or pathname string)) + (dev-group -1001234567890 :type integer) + (owner 12345678 :type integer)) + +(defvar *config* (make-config) + "Bot's configuration") + +(defun bot-name (&optional (config *config*)) + "Get the desired name for the bot" + (config-bot-name config)) + +(defun bot-token (&optional (config *config*)) + "Get the API token for the bot" + (config-bot-token config)) + +(defun db-path (&optional (config *config*)) + "Get the path to the bot's database" + (config-db-path config)) + +(defun dev-group (&optional (config *config*)) + "Get the ID of the dev/testing group" + (config-dev-group config)) + +(defun owner (&optional (config *config*)) + "Get the ID of the bot's owner" + (config-owner config)) + +(defun load-config (filename &optional (config *config*)) + "Load config from the given `filename'." + (prog1 config + (let ((data (with-open-file (f filename) (read f)))) + (iter + (for (kw-name value) on data by #'cddr) + (let ((name (intern (symbol-name kw-name) :ukkoclot/config))) + (setf (slot-value config name) value)))))) + +(defun serialize (config) + "Serializes the config to a plist." + (iter + (for slot in (class-direct-slots (class-of config))) + (appending + (let* ((name (slot-definition-name slot)) + (kw-name (intern (symbol-name name) :keyword))) + (list kw-name (slot-value config name)))))) + +(defun print-default (filename) + "Prints the default config to the given `filename'." + (with-open-file (f filename :direction :output :if-exists :supersede) + (format f ";; lint:suppress in-package spdx-license-identifier~%") + (format f ";; Copy this file to config.lisp and modify it there~%") + (let ((data (serialize (make-config)))) + (format f "~<(~;~@{~(~W~) ~W~^ ~_~}~;)~:>~%" data)))) -- cgit v1.2.3