Mercurial > core / lisp/lib/dat/toml.lisp
changeset 698: |
96958d3eb5b0 |
parent: |
686748796f08
|
author: |
Richard Westhaver <ellis@rwest.io> |
date: |
Fri, 04 Oct 2024 22:04:59 -0400 |
permissions: |
-rw-r--r-- |
description: |
fixes |
1 ;;; dat/toml.lisp --- TOML 3 ;; TOML de/serialization for Lisp. 7 ;; This code was originally based on https://github.com/sheepduke/clop which 8 ;; provides a TOML parser using the ESRAP package. 10 ;; ref: https://toml.io/en/v1.0.0 12 ;; grammar: https://raw.githubusercontent.com/toml-lang/toml/1.0.0/toml.abnf 15 * TOML is case-sensitive. 16 * A TOML file must be a valid UTF-8 encoded Unicode document. 17 * Whitespace means tab (0x09) or space (0x20). 18 * Newline means LF (0x0A) or CRLF (0x0D 0x0A). 22 (in-package :dat/toml) 26 "The value of +inf when decoding TOML.") 29 "The value of -inf when decoding TOML.") 32 "The value of +nan when decoding TOML.") 35 "The value of -nan when decoding TOML.") 37 (defclass toml-object () ()) 39 (defclass toml-table (toml-object) 40 ((table :initform (make-hash-table :test 'equal)))) 42 (defclass toml-inline-table (toml-table) ()) 44 (defclass toml-array-table (toml-table) ()) 46 (defclass toml-value (toml-object) ()) 48 (defclass toml-pair () 49 ((key :type (or symbol string) :initarg :key) (val :type toml-value :initarg :val))) 52 (defclass toml-document () 53 ((children :accessor children 54 :type (or list (vector toml-object)) 55 :documentation "A table of any kind. Note that for a table, its own name is not stored as a 56 property of itself, but as a hash key in children property of its parent 57 collection. The parsed result is a table representing root table."))) 60 (defun toml-read (stream &optional (eof-error-p t) eof-value) 61 (let ((c (peek-char t stream eof-error-p :eof))) 64 (#\[ (read-char stream) (toml-read-header stream)) ;; arrays are values only 65 (t (toml-read-key stream))))) 67 (defun toml-peek-char (stream expected &key skip-ws) 68 (when (equal (peek-char skip-ws stream) expected) 71 (defun toml-read-header (stream) 72 (let ((c (peek-char t stream nil nil))) 75 (#\[ (read-char stream) (toml-read-key stream)) 76 (t (toml-read-key stream))))) 78 (defun toml-read-key (stream)) 80 (defun toml-read-value (stream)) 82 (defun toml-read-pair (stream)) 87 (defgeneric parse-value (type value)) 89 (defmethod parse-value ((type (eql :datetime)) value) 91 (parse-timestring (ppcre:regex-replace " " "T" value))) 93 (defmethod parse-value ((type (eql :datetime-local)) value) 94 "Return a plist with keys (:year :month :day :hour :minute :second)." 95 (let* ((delimeter (sequence:elt value 10)) 96 (splits (split-sequence delimeter value))) 97 (append (parse-value :date-local (car splits)) 98 (parse-value :time-local (cadr splits))))) 100 (defmethod parse-value ((type (eql :date-local)) value) 101 "Return a plist with keys (:year :month :day)." 102 (let* ((*default-timezone* +utc-zone+) 103 (timestamp (parse-timestring value))) 104 (list :year (timestamp-year timestamp) 105 :month (timestamp-month timestamp) 106 :day (timestamp-day timestamp)))) 108 (defmethod parse-value ((type (eql :time-local)) value) 109 "Return a plist with keys (:hour :minute :second)." 110 (let* ((*default-timezone* +utc-zone+) 111 (timestamp (parse-timestring value))) 112 (list :hour (timestamp-hour timestamp) 113 :minute (timestamp-minute timestamp) 114 :second (timestamp-second timestamp) 115 :microsecond (timestamp-microsecond timestamp)))) 117 (defmethod parse-value (type value) 124 ;; (defun parse (text &key (style :alist)) 125 ;; "Parse given string TEXT and convert the result to given STYLE. 126 ;; The STYLE can be one of: 127 ;; * :alist (the default) 128 ;; * :raw (should be rarely used) 130 ;; The top-level of result is an alist. 132 ;; You may implement your own style by implementing SERIALIZE method." 133 ;; (let* ((parsed (esrap:parse 'toml text))) 134 ;; (serialize parsed style))) 136 ;; (defmethod serialize ((table toml-table) (format (eql :toml)) &key (style :alist)) 137 ;; (loop with children = (children table) 138 ;; for key being the hash-keys of children 139 ;; collect (cons key (serialize (gethash key children) format :style style)))) 141 ;; (defmethod serialize ((table inline-toml-table) (format (eql :toml)) &key (style :alist)) 142 ;; (loop with children = (children table) 143 ;; for key being the hash-keys of children 144 ;; collect (cons key (serialize (gethash key children) format :style style)))) 146 ;; (defmethod serialize ((table toml-table-array) (format (eql :toml)) &key style) 147 ;; (mapcar (lambda (it) (serialize it format :style style)) 148 ;; (children table))) 150 ;; (defmethod serialize (thing (format (eql :toml)) &key style) 151 ;; (declare (ignore style)) 154 ;; (defmethod serialize ((thing list) (format (eql :toml)) &key) 155 ;; (if (listp (cdr thing)) 156 ;; (mapcar (lambda (it) (serialize it :toml)) thing) 159 ;; (defmethod serialize (thing (format (eql :toml)) &key)