This is the set of utilities that I use when I need to handle it correctly falsewith cl-json:
(defclass json-false ()
())
(defmethod json:encode-json ((object json-false) &optional stream)
(princ "false" stream)
nil)
(defvar *json-false* (make-instance 'json-false))
(defun json-bool (val)
(if val t *json-false*))
(defun json-bool-handler (token)
(or (string= token "true")
(and (string= token "false") *json-false*)))
(defmacro preserving-json-boolean (opts &body body)
(declare (ignore opts))
`(let ((json:*boolean-handler* #'json-bool-handler))
,@body))
Now, to encode a literal false, I would do
* (json:encode-json-to-string `((foo . nil) (bar . t) (baz . ,*json-false*)))
"{\"foo\":null,\"bar\":true,\"baz\":false}"
Or, to encode a LISP boolean expression in json boolean:
* (let ((something nil))
(json:encode-json-to-string `((bool . ,(json-bool something)))))
"{\"bool\":false}"
Or, to read JSON data, keeping the distinction between nulland false:
* (preserving-json-boolean ()
(json:decode-json-from-string "{\"foo\":null,\"bar\":true,\"baz\":false}"))
((:FOO) (:BAR . T) (:BAZ .
Of course, care must be taken when reading in such data;
* (when (cdr (assoc :baz *))
'yep)
YEP
source
share