json-lib

2023-06-18

A simple and relatively fast JSON parser and encoder

Upstream URL

github.com/KinaKnowledge/json-lib

Author

Alex Nygren, KINA, LLC

License

MIT
README

JSON-Lib

JSON Parser and Serializer For Common Lisp

This is a simple json decoder and encoder that maps from JSON to Common Lisp and vice versa. The mappings are described in the following table. It strives to ensure no loss of fidelity in conversions of structured data between the two forms of representation.

This library has been tested to work with SBCL and CCL.

Mappings

JSONCommon Lisp
nullNIL
falseNIL
trueT
integerINTEGER
floatDOUBLE-FLOAT
stringString
arrayVECTOR
objectHASH-TABLE

How to Use

This library has two primary functions: parse, which takes a UTF-8 encoded JSON string and builds a representation of the structure in Common Lisp, and stringify, which takes a Common Lisp input structure and returns an output JSON string.

FUNCTIONINPUTOUTPUT
PARSEUTF-8 Encoded StringsCommon Lisp (see Mappings)
STRINGIFYCommon LispCommon Lisp String

parse [json-lib] input-string &key use-keywords-for-keys trace (max-depth 1000) (max-exponent-length 2))

Given an encoded UTF-8 JSON string, parse returns a Common Lisp structure or value. If use-keywords-for-keys is T, then hash table keys will be constructed as keywords. By default the limit is 1000 for structural depth, but this can be set with the keyword max-depth. Exponent representation in serialized form is limited to a length of 2 to prevent huge values causing slow downs and other issues in the conversion process.

stringify [json-lib] data &key (case-encoder #'lisp-to-snakecase) unencodable-items)

Stringify converts the given data structure to a stringified JSON form, suitable for serialization and other uses. An optional function can be passed for case encoding of native lisp keyword structures. If a function for unencodable-items is provided, this function will be called, and should return a JSON compliant string representing the encoded items. If no value is provided for unencodable-items, the JSON null value is used.

Examples

Parsing JSON to Common Lisp

To convert encoded JSON, pass a UTF-8 string buffer to the json-lib:parse function. For example, to read and parse a JSON encoded file:

(json-lib:parse (alexandria:read-file-into-string "file.json" 
                                                  :external-format :utf8))

Note that it is important to specify in your input stream conversions that UTF-8 should be used.

Serializing Common Lisp Structures to JSON

To get a serialized JSON string, pass a Lisp structure constructed with the listed types for Common Lisp in the Mappings table to the stringify function.

(json-lib:stringify #(1 2 3.14159 #("ABC" T "♥" nil)))

This will output a string as follows:

"[1, 2, 3.14159, [\"ABC\", true, \"♥\", null]]"

Specifics and Notes

This library is fairly forgiving from a parsing standpoint. Particularly, in parsing JSON, and in contrast with the JSON spec, commas are not required to delimit input JSON. The parser uses whitespace presence, regardless of commas, as a delimiting marker.

Compliance is measured to the JSONTestSuite Github repository tests. The function build-parser-test-harness (in compliance.lisp) will clone the JSONTestSuite repo into a subfolder in your current working directory and report out to STDOUT the validation results, plus returns a hashtable.

See the tests folder for specifics on SBCL and CCL compliance. This file can be generated with (build-parser-test-harness :write-compliance-html-file "compliance.html").

License

MIT

Dependencies (5)

  • alexandria
  • babel
  • cl-fad
  • cl-str
  • parse-float

Dependents (0)

    • GitHub
    • Quicklisp