Open kilianmh opened 1 year ago
I'm not sure whether to put it in the scope of the project or not. With CLOS one can do a method combination with json-to-clos
and add any validation necessary, including checking that required slots are present.
On the other hand, I have speculated about adding JSON schema support in #4, which would entail having this feature.
Indeed, with a method json-to-clos :after
and (input hash-table)
it should work:
(defmethod json-to-clos :after ((input hash-table) class &rest initargs)
(declare (ignore initargs))
(let ((class-object
(find-class class)))
(declare (type json-serializable-class class-object))
(loop for slot in (closer-mop:class-direct-slots class-object)
do (when (required slot)
(let ((json-key-name
(json-key-name slot)))
(declare (type string json-key-name))
(unless (gethash json-key-name input)
(error (concatenate 'string "The key \"" json-key-name "\" is not present in " (format nil "~A" input)
", but required in "(format nil "~A" class-object)"."))))))))
The only downside is that we have to find-class
, class-direct-slots
, and loop
two times, which decreases performance slightly.
The json-serializable-slot
class definition could look similar to this:
(defclass json-serializable-slot (closer-mop:standard-direct-slot-definition)
((json-key :initarg :json-key
:initform nil
:reader json-key-name)
(json-type :initarg :json-type
:initform :any
:reader json-type)
(required :initarg :required
:initform nil
:reader required)))
It is quite useful to specify required slots.
Therefore we can add an
required
slot to thejson-serializable-slot
class. Then in theinitialize-slots-from-json
function it will be checked for each required slot.I'm however not sure if there should be a warning or an error when a required slot is not present? @gschjetne