This is the jonathan Reference Manual, version 0.1, generated automatically by Declt version 4.0 beta 2 "William Riker" on Sun Dec 15 06:31:01 2024 GMT+0.
The main system appears first, followed by any subsystem dependency.
jonathan
High performance JSON encoder and decoder. Currently support: SBCL, CCL.
Rudolph-Miller
MIT
# Jonathan
[![Build Status](https://circleci.com/gh/Rudolph-Miller/jonathan.svg?style=shield)](https://circleci.com/gh/Rudolph-Miller/jonathan)
[![Build Status](https://travis-ci.org/Rudolph-Miller/jonathan.svg?branch=master)](https://travis-ci.org/Rudolph-Miller/jonathan)
[![Coverage Status](https://coveralls.io/repos/Rudolph-Miller/jonathan/badge.svg?branch=master)](https://coveralls.io/r/Rudolph-Miller/jonathan?branch=master)
[![Quicklisp dist](http://quickdocs.org/badge/jonathan.svg)](http://quickdocs.org/jonathan/)
JSON encoder and decoder.
It’s faster than [jsown](https://github.com/madnificent/jsown) - high performance Common Lisp json parser.
See [Document](http://rudolph-miller.github.io/jonathan/overview.html).
This HTML is generated by [Codex](https://github.com/CommonDoc/codex).
## Usage
“‘Lisp
(to-json ’(:name "Common Lisp" :born 1984 :impls (SBCL KCL)))
;; => "{\"NAME\":\"Common Lisp\",\"BORN\":1984,\"IMPLS\":[\"SBCL\",\"KCL\"]}"
(to-json ’(:name "Common Lisp" :born 1984 :impls (SBCL KCL))
:octets t)
;; => #(123 34 78 65 77 69 34 58 34 67 111 109 109 111 110 32 76 ...)
(to-json ’((:name . "Common Lisp") (:born . 1984) (:impls SBCL KCL))
:from :alist)
;; => "{\"NAME\":\"Common Lisp\",\"BORN\":1984,\"IMPLS\":[\"SBCL\",\"KCL\"]}"
(to-json ’(:obj (:name . "Common Lisp") (:born . 1984) (:impls SBCL KCL))
:from :jsown)
;; => "{\"NAME\":\"Common Lisp\",\"BORN\":1984,\"IMPLS\":[\"SBCL\",\"KCL\"]}"
(let ((encoder (compile-encoder (:from :alist) (name)
‘(("name" . ,name)))))
(funcall encoder "Rudolph"))
;; => "{\"name\":\"Rudolph\"}"
(parse "{\"NAME\":\"Common Lisp\",\"BORN\":1984,\"IMPLS\":[\"SBCL\",\"KCL\"]}")
;; => (:NAME "Common Lisp" :BORN 1984 :IMPLS ("SBCL" "CCL" "KCL"))
(parse "{\"NAME\":\"Common Lisp\",\"BORN\":1984,\"IMPLS\":[\"SBCL\",\"KCL\"]}"
:as :alist)
;; => (("NAME" . "Common Lisp") ("BORN" . 1984) ("IMPLS" "SBCL" "CCL" "KCL"))
(parse "{\"NAME\":\"Common Lisp\",\"BORN\":1984,\"IMPLS\":[\"SBCL\",\"KCL\"]}"
:as :jsown)
;; => (:obj ("NAME" . "Common Lisp") ("BORN" . 1984) ("IMPLS" "SBCL" "CCL" "KCL"))
(parse "{\"NAME\":\"Common Lisp\",\"BORN\":1984,\"IMPLS\":[\"SBCL\",\"KCL\"]}"
:as :hash-table)
;; => #<HASH-TABLE :TEST EQUAL :COUNT 3>
“‘
## Installasion
“‘Lisp
(ql:quickload :jonathan)
“‘
## to-json
- can encode Object into JSON format.
- Restricted Property List. (‘:from :plist‘)
- Association List. (‘:from :alist‘)
- Jsown Object. (‘:from :jsown‘)
- can return not only string but also octets.
- can be compiled by compiler-macro.
“‘Lisp
;; Restricted Property List Samples
(to-json ’(:name :age :born :impls))
;; => "{\"NAME\":\"AGE\",\"BORN\":\"IMPLS\"}"
;; not "[\"NAME\",\"AGE\",\"BORN\",\"IMPLS\"]"
(to-json ’(:name "Common Lisp" :born))
;; => "{\"NAME\":\"Common Lisp\",\"BORN\":[]}"
“‘
- is customizable by ‘%to-json‘, ‘%write-char‘ and ‘%write-string‘.
“‘Lisp
(defclass user ()
((id :type integer :initarg :id)
(name :type string :initarg :name)))
(defmethod %to-json ((user user))
(with-object
(write-key-value "id" (slot-value user ’id))
(write-key-value "name" (slot-value user ’name))))
(to-json (make-instance ’user :id 1 :name "Rudolph"))
;; => "{\"id\":1,\"name\":\"Rudolph\"}"
“‘
![Benchmark of to-json](./images/1.to-json.png)
“‘Lisp
(let ((post (compile-encoder () (text)
(list :|channel| "lisp-alien"
:|username| "alien-bot"
:|text| text
:|icon_url| "http://www.lisperati.com/lisplogo_warning2_256.png"))))
(time
(dotimes (_ 100000)
(funcall post "Post from Alien!"))))
;; => 0.095
(flet ((post (text)
(jonathan:to-json
(list :|channel| "lisp-alien"
:|username| "alien-bot"
:|text| text
:|icon_url| "http://www.lisperati.com/lisplogo_warning2_256.png"))))
(time
(dotimes (_ 100000)
(post "Post from Alien!"))))
;; => 0.095
(flet ((post (text)
(format nil "{\"channel\":\"lisp-alien\",\"username\":\"alien-bot\",\"text\":~s,\"icon_url\":\"http://www.lisperati.com/lisplogo_warning2_256.png\"}" text)))
(time
(dotimes (_ 100000)
(post "Post from Alien!"))))"\"}"))))
;; => 0.146
(flet ((post (text)
(jonathan:to-json
(list :|channel| "lisp-alien"
:|username| "alien-bot"
:|text| text
:|icon_url| "http://www.lisperati.com/lisplogo_warning2_256.png"))))
(time
(dotimes (_ 100000)
(post "Post from Alien!"))))
;; => 0.604 - without compiler-macro.
(flet ((post (text)
(jsown:to-json
‘(:obj (:|channel| . "lisp-alien")
(:|username| . "alien-bot")
(:|text| . ,text)
(:|icon_url| . "http://www.lisperati.com/lisplogo_warning2_256.png")))))
(time
(dotimes (_ 100000)
(post "Post from Alien!"))))
;; => 1.117
“‘
## parse
- can decode JSON format string into Object.
- Property List. (‘:as :plist‘)
- Association List. (‘:as :alist‘)
- Json Object. (‘:as :jsown‘)
- Hash Table. (‘:as :hash-table‘)
- can allow junked JSON format string (‘:junk-allowed t‘)
- can customize ‘*null-value*‘, ‘*false-value*‘ and ‘*empty-array-value*‘.
- can restrict keywords to read. (‘:keywords-to-read‘)
- can normalize keywords. (‘:keyword-normalizer‘)
- can not normalize keywords in nested objects.
- can ignore keywords when normalizer returns NIL.
- can unescape unicode escape sequences. (‘:unescape-unicode-escape-sequence‘)
“‘Lisp
(parse "{\"key\":\"value\"}")
;; => (:|key| "value")
(parse "{\"key\":\"value\"")
;; => raise <jonathan-unexpected-eof>.
(parse "{\"key\":\"value\"" :junk-allowed t)
;; => (:|key| "value")
(let ((*null-value* :null)
(*false-value* :false)
(*empty-array-value* :[]))
(parse "{\"null\":null,\"false\":false,\"empty\":[]}"))
;; => (:|null| :NULL :|false| :FALSE :|empty| :[])
(parse "{\"key1\":\"value1\",\"key2\":\"value2\"}" :keywords-to-read ’("key1"))
;; => (:|key1| "value1")
(flet ((normalizer (key)
(with-vector-parsing (key)
(match-i-case
("key1" (return-from normalizer "other-key1"))
("key2" (return-from normalizer "other-key2"))
(otherwise (return-from normalizer nil))))))
(parse "{\"KEY1\":{\"key2\":\"value2\"},\"key3\":\"value3\"}"
:keyword-normalizer #’normalizer)
;; => (:|other-key1| (:|key2| "value2"))
(parse "{\"KEY1\":{\"key2\":\"value2\"},\"key3\":\"value3\"}"
:keyword-normalizer #’normalizer
:normalize-all t))
;; => (:|other-key1| (:|other-key2| "value2"))
(parse "\"\\u30b8\\u30e7\\u30ca\\u30b5\\u30f3\"")
;; => "ジョナサン"
(parse "\"\\uD840\\uDC0B\"")
;; => "𠀋"
(parse "\"\\u30b8\\u30e7\\u30ca\\u30b5\\u30f3\""
:unescape-unicode-escape-sequence nil)
;; => "\u30b8\u30e7\u30ca\u30b5\u30f3"
“‘
![Benchmark of parse](./images/2.parse.png)
“‘Lisp
(let ((s "{\"key1\":\"value\",\"key2\":1.1,\"key3\":[\"Hello\",1.2]}"))
(time
(dotimes (_ 100000)
(jonathan:parse s :as :alist))))
;; => 0.174
(let ((s "{\"key1\":\"value\",\"key2\":1.1,\"key3\":[\"Hello\",1.2]}"))
(time
(dotimes (_ 100000)
(jonathan:parse s :as :jsown))))
;; => 0.181
(let ((s "{\"key1\":\"value\",\"key2\":1.1,\"key3\":[\"Hello\",1.2]}"))
(time
(dotimes (_ 100000)
(jsown:parse s))))
;; => 0.204
“‘
![Benchmark of parse partially](./images/3.parse-partially.png)
“‘Lisp
(let ((s "{\"key1\":\"value\",\"key2\":1.1,\"key3\":[\"Hello\",1.2]}"))
(time
(dotimes (_ 100000)
(jonathan:parse s :as :alist :keywords-to-read ’("key1")))))
;; => 0.065
(let ((s "{\"key1\":\"value\",\"key2\":1.1,\"key3\":[\"Hello\",1.2]}"))
(time
(dotimes (_ 100000)
(jonathan:parse s :as :jsown :keywords-to-read ’("key1")))))
;; => 0.069
(let ((s "{\"key1\":\"value\",\"key2\":1.1,\"key3\":[\"Hello\",1.2]}"))
(time
(dotimes (_ 100000)
(jsown:parse s "key1"))))
;; => 0.085
“‘
## Helper
### compile-encoder
- can compile encoder.
“‘Lisp
(compile-encoder () (name)
(list :name name))
;; => #<FUNCTION (LAMBDA (name))>
(funcall * "Rudolph")
;; => "{\"NAME\":\"Rudolph\"}"
(compile-encoder (:from :alist) (name)
‘(("name" . ,name)))
;; => #<FUNCTION (LAMBDA (name))>
(funcall * "Rudolph")
;; => "{\"name\":\"Rudolph\"}"
(compile-encoder (:octets t) (name)
(list :name name))
;; => #<FUNCTION (LAMBDA (name))>
(funcall * "Rudolph")
;; => #(123 34 75 69 89 49 ...)
“‘
### with-object
“‘Lisp
(defclass user ()
((id :initarg :id)
(name :initarg :name)))
(defmethod %to-json ((user user))
(with-object
(write-key "id")
(write-value (slot-value user ’id))
(write-key-value "name" (slot-value user ’name))))
(to-json (make-instance ’user :id 1 :name "Rudolph"))
;; => "{\"id\":1,\"name\":\"Rudolph\"}"
“‘
### with-array
“‘Lisp
(defclass user ()
((id :initarg :id)
(name :initarg :name)))
(defmethod %to-json ((user user))
(with-array
(write-item "id")
(write-item (slot-value user ’id))
(write-item "name")
(write-item (slot-value user ’name))))
(to-json (make-instance ’user :id 1 :name "Rudolph"))
;; => "[\"id\",1,\"name\",\"Rudolph\"]"
“‘
### with-output
“‘Lisp
(with-output-to-string (stream)
(with-output (stream)
(with-object
(write-key-value "key" "value"))))
;; => "{\"key\":\"value\"}"
“‘
### with-output-to-string*
“‘Lisp
(with-output-to-string*
(with-object
(write-key-value "key" "value"))))
;; => "{\"key\":\"value\"}"
“‘
## See Also
- [proc-parse](https://github.com/fukamachi/proc-parse)
## Author
- Rudolph-Miller
## Copyright
Copyright (c) 2015 Rudolph-Miller
0.1
cl-syntax
(system).
cl-syntax-annot
(system).
fast-io
(system).
trivial-types
(system).
babel
(system).
proc-parse
(system).
cl-ppcre
(system).
cl-annot
(system).
src
(module).
Modules are listed depth-first from the system components tree.
jonathan/src
jonathan
(system).
jonathan.lisp
(file).
helper.lisp
(file).
encode.lisp
(file).
decode.lisp
(file).
util.lisp
(file).
error.lisp
(file).
Files are sorted by type and then listed depth-first from the systems components trees.
jonathan/jonathan.asd
jonathan/src/jonathan.lisp
jonathan/src/helper.lisp
jonathan/src/encode.lisp
jonathan/src/decode.lisp
jonathan/src/util.lisp
jonathan/src/error.lisp
jonathan/src/jonathan.lisp
encode.lisp
(file).
decode.lisp
(file).
helper.lisp
(file).
error.lisp
(file).
src
(module).
jonathan/src/helper.lisp
encode.lisp
(file).
decode.lisp
(file).
error.lisp
(file).
src
(module).
compile-encoder
(macro).
to-json
(compiler macro).
with-output-to-string*
(macro).
*compile-encoder-prefix*
(special variable).
check-args
(function).
normalize-form
(function).
replace-form-with-placeholders
(function).
jonathan/src/encode.lisp
util.lisp
(file).
error.lisp
(file).
src
(module).
%to-json
(generic function).
%write-char
(function).
%write-string
(function).
*from*
(special variable).
*octets*
(special variable).
*stream*
(special variable).
to-json
(function).
with-array
(macro).
with-object
(macro).
with-output
(macro).
write-item
(macro).
write-key
(macro).
write-key-value
(macro).
write-value
(macro).
alist-to-json
(function).
list-to-json
(function).
plist-to-json
(function).
string-to-json
(function).
with-macro-p
(macro).
jonathan/src/decode.lisp
util.lisp
(file).
src
(module).
*empty-array-value*
(special variable).
*empty-object-value*
(special variable).
*false-value*
(special variable).
*null-value*
(special variable).
parse
(compiler macro).
parse
(function).
*inner-nest-p*
(special variable).
foldable-keywords-to-read-p
(function).
make-normalizer
(macro).
jonathan/src/util.lisp
error.lisp
(file).
src
(module).
*quasiquote*
(special variable).
+impl-comma-p+
(special variable).
comma-expr
(function).
comma-p
(function).
integer-char-p
(function).
make-keyword
(function).
my-plist-p
(function).
jonathan/src/error.lisp
src
(module).
<jonathan-error>
(condition).
<jonathan-incomplete-json-error>
(condition).
<jonathan-not-supported-error>
(condition).
<jonathan-unexpected-eof-error>
(condition).
<jonathan-without-tail-surrogate-error>
(condition).
Packages are listed by definition order.
jonathan.encode
cl-annot.doc
.
common-lisp
.
jonathan.util
.
%to-json
(generic function).
%write-char
(function).
%write-string
(function).
*from*
(special variable).
*octets*
(special variable).
*stream*
(special variable).
to-json
(compiler macro).
to-json
(function).
with-array
(macro).
with-object
(macro).
with-output
(macro).
write-item
(macro).
write-key
(macro).
write-key-value
(macro).
write-value
(macro).
alist-to-json
(function).
list-to-json
(function).
plist-to-json
(function).
string-to-json
(function).
with-macro-p
(macro).
jonathan.helper
cl-annot.doc
.
common-lisp
.
jonathan.encode
.
jonathan.error
.
jonathan.util
.
compile-encoder
(macro).
with-output-to-string*
(macro).
*compile-encoder-prefix*
(special variable).
check-args
(function).
normalize-form
(function).
replace-form-with-placeholders
(function).
jonathan.error
common-lisp
.
<jonathan-error>
(condition).
<jonathan-incomplete-json-error>
(condition).
<jonathan-not-supported-error>
(condition).
<jonathan-unexpected-eof-error>
(condition).
<jonathan-without-tail-surrogate-error>
(condition).
jonathan.util
common-lisp
.
jonathan.error
.
*quasiquote*
(special variable).
+impl-comma-p+
(special variable).
comma-expr
(function).
comma-p
(function).
integer-char-p
(function).
make-keyword
(function).
my-plist-p
(function).
jonathan.decode
cl-annot.doc
.
common-lisp
.
jonathan.error
.
jonathan.util
.
proc-parse
.
*empty-array-value*
(special variable).
*empty-object-value*
(special variable).
*false-value*
(special variable).
*null-value*
(special variable).
parse
(compiler macro).
parse
(function).
*inner-nest-p*
(special variable).
foldable-keywords-to-read-p
(function).
make-normalizer
(macro).
Definitions are sorted by export status, category, package, and then by lexicographic order.
LISP value of [].
LISP value of {}.
LISP value of false.
Default value of from used by #’to-json.
LISP value of null.
Default value of octets used by #’to-json.
Stream used by #’to-json.
Compile encoder.
Make writing array safe.
Make writing object safe.
Bind *stream* to stream.
Output *stream* as string.
Write item of array.
Write key part of object.
Write key and value of object.
Write value part of object.
Write character to *stream*.
Write string to *stream*.
Convert JSON String to LISP object.
Convert LISP object to JSON String.
Write obj as JSON string.
(eql nil)
)) ¶(eql :empty)
)) ¶(eql :null)
)) ¶(eql :false)
)) ¶(eql t)
)) ¶symbol
)) ¶hash-table
)) ¶vector
)) ¶list
)) ¶ratio
)) ¶float
)) ¶number
)) ¶string
)) ¶Base condition of jonathan-errors.
simple-error
.
Incomplete JSON string error.
Parsing objcet slot.
:object
Not supported object slot.
:object
Unexpecded EOF error.
Parsing object slot.
:object
Jump to: | %
A C F G I L M N P R S T W |
---|
Jump to: | %
A C F G I L M N P R S T W |
---|
Jump to: | *
+
O S |
---|
Jump to: | *
+
O S |
---|
Jump to: | <
C D E F H J M P S U |
---|
Jump to: | <
C D E F H J M P S U |
---|