diff --git a/README.md b/README.md index 2554d68..f457854 100644 --- a/README.md +++ b/README.md @@ -263,11 +263,14 @@ When writing, the following type mappings are also available: | character | string (`string`) | | pathname | string (`uiop:native-namestring`) | | real | number | +| array | array\* - multidimensional arrays are arrays-of-arrays | | sequence | array | | standard-object | object | -| structure-object\* | object | +| structure-object† | object | -\*: On supported implementations where structure slots are available via the MOP. +\*: `#2A((1 2) (3 4))` becomes `[[1,2],[3,4]]` + +†: On supported implementations where structure slots are available via the MOP. If you have an alist/plist you wish to write, we recommend the use of either `alexandria:alist-hash-table` or `alexandria:plist-hash-table`, or use one of the methods in [Custom Serialization](#custom-serialization). diff --git a/src/jzon.lisp b/src/jzon.lisp index 3a0c5f6..8e92dec 100644 --- a/src/jzon.lisp +++ b/src/jzon.lisp @@ -1408,6 +1408,21 @@ see `write-values'" (:method ((writer writer) (value pathname)) (%write-json-atom writer (uiop:native-namestring value))) + ;; Multi-dimensional arrays + (:method ((writer writer) (value array)) + (let ((dimensions (array-dimensions value))) + (if (null dimensions) + (write-value writer (aref value)) + (labels ((recurse (dimensions acc) + (destructuring-bind (d . rest) dimensions + (with-array writer + (if (null rest) + (loop :for i :below d + :do (write-value writer (row-major-aref value (+ acc i)))) + (loop :for i :below d + :do (recurse rest (+ acc (* i d))))))))) + (recurse dimensions 0))))) + ;;; Sequence support (:method ((writer writer) (value sequence)) (with-array writer diff --git a/test/jzon-tests.lisp b/test/jzon-tests.lisp index 4b66fdb..e988065 100644 --- a/test/jzon-tests.lisp +++ b/test/jzon-tests.lisp @@ -764,6 +764,12 @@ ] ]" (jzon:stringify #(#(1 2) #(3 4)) :pretty t)))) +(test stringify-multidimensional-array + (is (string= "[[1,2],[3,4]]" (jzon:stringify #2A((1 2) (3 4)))))) + +(test 0-dimension-array + (is (string= "42" (jzon:stringify #0A42)))) + (defun recode (value) "Shorthand for (jzon:parse (jzon:stringify value))" (jzon:parse (jzon:stringify value))) @@ -855,9 +861,6 @@ } ]" (jzon:stringify (vector (ph "x" 0)) :pretty t)))) -(test stringify-no-slots-on-unknown-object () - (is (string= "{}" (jzon:stringify (make-array '(2 2)))))) - (test stringify-pretty-prints-keys (is (string= "{\"#(1 2)\":0}" (jzon:stringify (ph #(1 2) 0)))))