Skip to content

Commit

Permalink
Support json-type (:hash-table object)
Browse files Browse the repository at this point in the history
  • Loading branch information
riktam committed Aug 30, 2023
1 parent af3286a commit c444dcb
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 3 deletions.
19 changes: 19 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
*.FASL
*.abcl
*.d64fsl
*.dfsl
*.dx32fsl
*.dx64fsl
*.fasl
*.fx32fsl
*.fx64fsl
*.lisp-temp
*.lx32fsl
*.lx64fsl
*.p64fsl
*.pfsl
*.sx32fsl
*.sx64fsl
*.wx32fsl
*.wx64fsl
*~
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ Type | Remarks
`:bool` | Maps `T` and `NIL` with `true` and `false`
`<symbol>` | Uses a `(:metaclass json-serializable-class)` class definition to direct the transformation of the value

### Homogeneous sequences
### Homogeneous sequences and objects

In addition, the type specifier may be a list of two elements, first
element is one of `:list`, `:vector`; the second is any JSON type
specifier that is to be applied to the elements of the list.
element is one of `:list`, `:vector`, `:hash-table`; the second is any JSON type
specifier that is to be applied to the elements of the list or the values of the hash-table.

### NIL and null semantics

Expand Down
27 changes: 27 additions & 0 deletions src/to-json.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,20 @@
"Return the boolean false"
'false)

(defclass homogeneous-hash-table-intermediate-class ()
((values :initarg :values)
(hash-table-json-type :initarg :hash-table-json-type)
(element-json-type :initarg :element-json-type)))

(defmethod to-json-value ((value hash-table) (json-type cons))
"Return the homogeneous hash-table VALUE"
(ecase (first json-type)
(:hash-table (check-type value hash-table)))
(make-instance 'homogeneous-hash-table-intermediate-class
:values value
:hash-table-json-type (first json-type)
:element-json-type (second json-type)))

(defmethod to-json-value ((value sequence) (json-type cons))
"Return the homogeneous sequence VALUE"
(ecase (first json-type)
Expand Down Expand Up @@ -107,6 +121,19 @@
values))))
sequence)

(defmethod encode ((hash-table homogeneous-hash-table-intermediate-class)
&optional (stream *standard-output*))
(with-output (stream)
(with-object ()
(with-slots (values hash-table-json-type element-json-type)
hash-table
(maphash (lambda (key value)
(encode-object-element
(to-json-value key :string)
(to-json-value value element-json-type)))
values))))
hash-table)

(defmethod encode ((object json-serializable)
&optional (stream *standard-output*))
(with-output (stream)
Expand Down
12 changes: 12 additions & 0 deletions src/to-lisp.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@
"Return the hash-table VALUE"
value)

(defmethod to-lisp-value ((value hash-table) (json-type cons))
"Return the homogeneous hash-table VALUE"
(destructuring-bind (hash-keyword out-type)
json-type
(ecase hash-keyword
(:hash-table
(let ((out (make-hash-table :test 'equal :size (hash-table-size value))))
(maphash (lambda (k v)
(setf (gethash k out) (to-lisp-value v out-type)))
value)
out)))))

(defmethod to-lisp-value ((value vector) (json-type (eql :vector)))
"Return the vector VALUE"
value)
Expand Down
5 changes: 5 additions & 0 deletions tests/encode-decode.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@
(is (equalp (get-any-hash-table obj)
(get-any-hash-table (obj-rt obj))))))

(test obj-hash-table
(for-all ((obj (gen-object)))
(is (equalp (get-obj-hash-table obj)
(get-obj-hash-table (obj-rt obj))))))

(test inheritance-encode
(let ((child (make-instance 'child))
(parent-only (make-instance 'parent)))
Expand Down
8 changes: 8 additions & 0 deletions tests/tests.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
:reader get-any-hash-table
:json-type :any
:json-key "anyHash")
(obj-hash :initarg :obj-hash-table
:reader get-obj-hash-table
:json-type (:hash-table (:vector :string))
:json-key "objHash")
(vector :initarg :vector
:reader get-vector
:json-type :vector
Expand Down Expand Up @@ -116,6 +120,9 @@
(string (gen-string))
(number (gen-float))
(hash-table (gen-hash-table))
(obj-hash-table
(gen-hash-table
:elements (gen-vector :elements (gen-string))))
(vector (gen-vector))
(list (gen-list))
(bool (gen-bool))
Expand All @@ -129,6 +136,7 @@
:number (funcall number)
:hash-table (funcall hash-table)
:any-hash-table (funcall hash-table)
:obj-hash-table (funcall obj-hash-table)
:vector (funcall vector)
:list (funcall list)
:bool (funcall bool)
Expand Down

0 comments on commit c444dcb

Please sign in to comment.