### Jzon Streaming Writer Example Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md An example demonstrating how to implement a streaming JSON stringifier using Jzon. ```APIDOC ## Streaming Writer Example ### Description An example demonstrating how to implement a streaming JSON stringifier using Jzon. ### Code Example ```lisp (defun my/jzon-stringify (value) (labels ((recurse (value) (etypecase value (jzon:json-atom (jzon:write-value* value)) (vector (jzon:with-array* (map nil #'recurse value))) (hash-table (jzon:with-object* (maphash (lambda (k v) (jzon:write-key* k) (recurse v)) value)))))) (with-output-to-string (s) (jzon:with-writer* (:stream s) (recurse value))))) ``` ``` -------------------------------- ### REPL Example: Initialize and Begin Array with jzon:writer (Lisp) Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Provides a practical example for interactive use (REPL) in Lisp, demonstrating how to initialize a `jzon:writer` targeting standard output with pretty-printing enabled, and subsequently begin a JSON array using `jzon:begin-array*`. ```lisp #| Bind `jzon:*writer*` | (setf jzon:*writer* (jzon:make-writer :stream *standard-output* :pretty t)) #| Start an array so we can write multiple values | (jzon:begin-array*) ``` -------------------------------- ### Streaming Writer Example in Lisp Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Provides an example implementation of a streaming JSON writer using Jzon. This function, `my/jzon-stringify`, recursively handles different data types (atoms, vectors, hash tables) and writes them to an output stream. ```lisp (defun my/jzon-stringify (value) (labels ((recurse (value) (etypecase value (jzon:json-atom (jzon:write-value* value)) (vector (jzon:with-array* (map nil #'recurse value))) (hash-table (jzon:with-object* (maphash (lambda (k v) (jzon:write-key* k) (recurse v)) value)))))) (with-output-to-string (s) (jzon:with-writer* (:stream s) (recurse value))))) ``` -------------------------------- ### Begin and End Object in Lisp Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Illustrates how to start and finish writing a JSON object using jzon:begin-object and jzon:end-object. This requires explicit calls to define the object's scope and write its properties. ```lisp (jzon:begin-object*) (jzon:write-property* "age" 42) (jzon:end-object*) ``` -------------------------------- ### Begin and End Array in Lisp Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Demonstrates how to start and finish writing a JSON array using jzon:begin-array and jzon:end-array. This method requires explicit calls to mark the array's boundaries and write its values. ```lisp (jzon:begin-array*) (jzon:write-value* 0) (jzon:write-value* 1) (jzon:write-value* 2) (jzon:end-array*) ``` -------------------------------- ### Example JSON Serialization with jzon:write-value (Lisp) Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Demonstrates the usage of jzon:stringify with a custom job instance after specializing jzon:write-value. It shows how the custom serialization logic transforms the job object into different JSON structures based on its properties. ```lisp (jzon:stringify (make-instance 'job :company "WISE" :title "Agent") :stream t :pretty t) ``` ```lisp (jzon:stringify (make-instance 'job :company "The Butcher" :title "Assassin") :stream t :pretty t) ``` ```lisp (jzon:stringify (make-instance 'job :company "State Police" :title "Interrogator") :stream t :pretty t) ``` -------------------------------- ### jonathan vs jzon: Performance and Correctness Comparison Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Discusses performance discrepancies between jonathan and jzon, particularly with larger JSON files. It also points out correctness issues in jonathan, showing examples where it fails on malformed input, unlike jzon. ```common-lisp ;; jonathan example of incorrect parsing ;; (jonathan:parse "12,???") ; May lead to errors ;; (jonathan:parse 2) ; May lead to memory faults ;; jzon handles these safely (jzon:parse "12,???") ; Returns 12 (jzon:parse 2) ; Returns 2 ``` -------------------------------- ### Serialize Hash Table with Symbol Key Case Handling - jzon Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Illustrates how jzon:stringify handles symbol keys in hash tables, demonstrating its default behavior of downcasing symbol names unless they contain mixed-case characters. This example shows the transformation of different symbol key types when serialized to JSON, highlighting the case conversion rules. ```lisp (let ((ht (make-hash-table :test 'equal))) (setf (gethash 'only-keys ht) 'are-affected) (setf (gethash '|noChange| ht) '|when used|) (setf (gethash "AS A" ht) '|value|) (jzon:stringify ht :pretty t :stream t)) ``` -------------------------------- ### Streaming JSON Parser Implementation Example Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md An example implementation of a streaming JSON parser using jzon:parse-next. This function processes JSON input, handling different event types (value, begin/end array/object, object key) to reconstruct the JSON structure. ```lisp (defun my/jzon-parse (in) (jzon:with-parser (parser in) (let (top stack key) (flet ((finish-value (value) (typecase stack (null (setf top value)) ((cons list) (push value (car stack))) ((cons hash-table) (setf (gethash (pop key) (car stack)) value))))) (loop (multiple-value-bind (event value) (jzon:parse-next parser) (ecase event ((nil) (return top)) (:value (finish-value value)) (:begin-array (push (list) stack)) (:end-array (finish-value (coerce (the list (nreverse (pop stack))) 'simple-vector))) (:begin-object (push (make-hash-table :test 'equal) stack)) (:object-key (push value key)) (:end-object (finish-value (pop stack)))))))))) ``` -------------------------------- ### jsown vs jzon: Correctness and Safety Comparison Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Highlights critical correctness and safety issues found in the jsown library, contrasting them with jzon's robust handling of invalid JSON. This snippet includes examples of jsown failing on malformed input, potentially leading to crashes, while jzon handles them gracefully. ```common-lisp ;; jsown examples of incorrect parsing ;; (jsown:parse ",1,what]") ; May produce incorrect results or crash ;; (jsown:parse "[,1,what]") ; May crash ;; jzon handles these safely (jzon:parse ",1,what]") ; Returns 1 (jzon:parse "[,1,what]") ; Returns (1) ``` -------------------------------- ### Serialize Array to Pretty JSON with Replacer - jzon Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Demonstrates serializing a Common Lisp array to a pretty-printed JSON string using jzon:stringify. The :replacer function customizes how elements are included or transformed, handling specific keys to either include, exclude, or modify values. This example showcases conditional inclusion and value modification during the serialization process. ```lisp (jzon:stringify #("first" "second" "third") :stream t :pretty t :replacer (lambda (key value) (case key #| Always include toplevel |# ((nil) t) #| Do not include |# (0 nil) #| Include |# (1 t) #| Include, but replace |# (2 (values t (format nil "Lupin the ~A" value)))))) ``` -------------------------------- ### Load jzon using Quicklisp Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md This snippet demonstrates how to load the jzon library using Quicklisp, a popular Lisp implementation and package manager. It's the standard way to include external libraries in a Common Lisp project. ```lisp (ql:quickload '#:com.inuoe.jzon) ``` -------------------------------- ### Create a jzon:writer Instance (Lisp) Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Shows how to create a `jzon:writer` instance using the `jzon:make-writer` function in Lisp. It details the available arguments for configuring the writer, such as the output stream, pretty-printing, key coercion, replacer functions, and maximum nesting depth. ```lisp (jzon:make-writer :stream *standard-output* :pretty t :coerce-key nil :replacer nil :max-depth t) ``` -------------------------------- ### Set up local nickname for jzon (General) Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md This snippet provides a method for setting up a local nickname for the 'com.inuoe.jzon' package using the 'uiop' library, which is common across various Common Lisp implementations. This simplifies code by allowing shorter references to jzon functions. ```lisp (uiop:add-package-local-nickname '#:jzon '#:com.inuoe.jzon) ``` -------------------------------- ### Parsing JSON with jzon Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Demonstrates the basic usage of jzon:parse to convert various input types (string, octet vector, stream, pathname) into Common Lisp objects. It highlights the library's flexibility in input handling and its adherence to standard JSON parsing. ```common-lisp (jzon:parse "{\"key\": \"value\"}") (jzon:parse #.(babel:string-to-octets "{\"key\": \"value\"}")) (with-input-from-string (s "{\"key\": \"value\"}") (jzon:parse s)) (jzon:parse "path/to/file.json") ``` -------------------------------- ### jzon:make-parser Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Creates a parser instance from various input sources (string, vector, stream, pathname, span) with configurable options. ```APIDOC ### jzon:make-parser *Function* **jzon:make-parser** *in &key allow-comments allow-trailing-comma *allow-multiple-content* max-string-length key-fn* *=> writer* * *in* - a string, vector (unsigned-byte 8), stream, pathname, or [`jzon:span`](#jzonspan) * *allow-comments* - a `boolean` * *allow-trailing-comma* - a `boolean` * *allow-multiple-content* - a `boolean` * *max-string-length* - a positive `integer` * *key-fn* - a designator for a function of one argument, or a boolean *value* - a `jzon:parser` #### Description Creates a parser from `in` for use in subsequent [`jzon:parse-next`](#jzonparse-next). The behaviour of `jzon:parser` is analogous to `jzon:parse`, except you control the interpretation of the JSON events. `in` can be any of the following types: `string`, `(vector (unsigned-byte 8))`, `stream`, `pathname`, or [`jzon:span`]. When *max-string-length* is exceeded, [`jzon:parse-next`](#jzonparse-next) shall signal a `jzon:json-parse-limit-error` error. JSON requires there be only one toplevel element. Using *allow-multiple-content* allows parsing of multiple toplevel JSON elements. :warning: Because [`jzon:make-parser`](#jzonmake-parser) can open a file, it is recommended you use [`jzon:with-parser`](#jzonwith-parser) instead, unless you need indefinite extent. ``` -------------------------------- ### Standard Object Serialization with jzon Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Demonstrates serializing Common Lisp standard objects to JSON using `jzon:stringify`. It shows how different field types (unbound, nil, boolean, list) are represented in JSON. This requires the jzon library. ```lisp (defclass job () ((company :initarg :company :reader company) (title :initarg :title :reader title))) (defclass person () ((name :initarg :name :reader name) (alias :initarg :alias) (job :initarg :job :reader job) (married :initarg :married :type boolean) (children :initarg :children :type list))) ;; Example 1: Basic serialization with nil and unbound fields (jzon:stringify (make-instance 'person :name "Anya" :job nil :married nil :children nil) :pretty t :stream t) ;; Example 2: Serialization with bound fields and nested objects (jzon:stringify (make-instance 'person :name "Loid" :alias "Twilight" :job (make-instance 'job :company "WISE" :title "Agent") :married t :children (list (make-instance 'person :name "Anya" :job nil :married nil :children nil))) :pretty t :stream t) ``` -------------------------------- ### Safe JSON Parsing with jzon:parse and :max-depth Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Shows how jzon:parse is implemented iteratively to prevent stack exhaustion. It also demonstrates the use of the :max-depth option to guard against excessively nested JSON structures, enhancing safety. ```common-lisp (jzon:parse "{\"a\": 1}" :max-depth 100) ;; Example of potentially unsafe input for other libraries (jzon:parse "[,1,what]") ; jzon handles this safely ``` -------------------------------- ### Object Key Pooling in jzon Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Demonstrates how jzon pools object keys by default to optimize for duplicate keys in JSON payloads. The `:key-fn` argument can be used to alter this behavior. ```lisp (jzon:parse "[{\"x\": 5}, {\"x\": 10}, {\"x\": 15}]") ``` -------------------------------- ### Streaming JSON Writing with jzon:with-writer Source: https://context7.com/zulu-inuoe/jzon/llms.txt Illustrates how to construct JSON output incrementally using a streaming writer. This is beneficial for generating large JSON documents or implementing custom serialization logic. It supports various methods, including convenience macros and dynamic variable interfaces. ```lisp ;; Basic streaming writer (jzon:with-writer (writer :stream t :pretty t) (jzon:begin-object writer) (jzon:write-key writer "name") (jzon:write-value writer "Alice") (jzon:write-key writer "scores") (jzon:begin-array writer) (jzon:write-value writer 95) (jzon:write-value writer 87) (jzon:write-value writer 92) (jzon:end-array writer) (jzon:end-object writer)) ;; Output: ;; { ;; "name": "Alice", ;; "scores": [ ;; 95, ;; 87, ;; 92 ;; ] ;; } ;; Using convenience macros and functions (jzon:with-writer (w :stream t :pretty t) (jzon:with-object w (jzon:write-property w "id" 123) (jzon:write-properties w "type" "user" "active" t) (jzon:write-key w "tags") (jzon:write-array w "admin" "developer"))) ;; Output: ;; { ;; "id": 123, ;; "type": "user", ;; "active": true, ;; "tags": [ ;; "admin", ;; "developer" ;; ] ;; } ;; Using dynamic variable interface (*writer*) (jzon:with-writer* (:stream t :pretty t) (jzon:with-object* (jzon:write-property* :name "Bob") (jzon:write-key* "items") (jzon:with-array* (jzon:write-values* 1 2 3)))) ``` -------------------------------- ### Equivalent jzon:writer Usage (Lisp) Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Illustrates two equivalent ways of using the `jzon:writer` API in Lisp. The first uses the `jzon:with-writer*` macro which binds the `jzon:*writer*` special variable. The second explicitly passes the writer object to the `write-value*` function, demonstrating the alternative syntax. ```lisp (jzon:with-writer* () (write-value* "foo")) ``` ```lisp (with-writer (writer) (write-value writer "foo")) ``` -------------------------------- ### Write Object Key and Value Separately in Lisp Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Shows how to write an object key using jzon:write-key and then its corresponding value using jzon:write-value within a jzon:with-object block. This provides granular control over property serialization. ```lisp (jzon:with-object* (jzon:write-key* "age") (jzon:write-value* 42)) ``` -------------------------------- ### Write an Entire Array in Lisp Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Demonstrates the jzon:write-array function, which creates, populates, and closes a JSON array in a single call. This is the most concise way to write a simple array. ```lisp (jzon:write-array* 0 1 2) ``` -------------------------------- ### Set up local nickname for jzon (SBCL) Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md This code configures a local nickname for the 'com.inuoe.jzon' package specifically for the SBCL (Steel Bank Common Lisp) implementation. This allows for shorter, more convenient references to jzon functions in the REPL. ```lisp (sb-ext:add-package-local-nickname '#:jzon '#:com.inuoe.jzon) ``` -------------------------------- ### jzon:with-parser Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md A macro that provides a convenient way to create, use, and automatically close a parser, similar to `with-open-file`. ```APIDOC ### jzon:with-parser *Macro* **jzon:with-parser** *(var &rest args) declaration* form* * *var* - a symbol. * *declaration* - a declare expression; not evaluated. * *form* - an implicit progn #### Description As [`jzon:make-parser`](#jzonmake-parser) + `unwind-protect` + [`jzon:close-parser`](#jzonclose-parser). Use this like you would `with-open-file`. ``` -------------------------------- ### jzon:stringify - Serialize to JSON Source: https://context7.com/zulu-inuoe/jzon/llms.txt Converts Common Lisp values into JSON strings. It supports writing to various destinations like streams and files, offers pretty-printing, and allows customization through key coercion and replacer functions. ```APIDOC ## jzon:stringify - Serialize Values to JSON ### Description Converts Common Lisp values to JSON strings. Supports various stream destinations, pretty printing, custom key coercion, and replacer functions for filtering or transforming values during serialization. ### Method `jzon:stringify` ### Parameters #### Path Parameters None #### Query Parameters - **value**: (any) - The Common Lisp value to serialize. - **:stream**: (stream or boolean) - If a stream, writes the JSON to that stream. If true, writes to `*standard-output*`. - **:pretty**: (boolean) - If true, formats the output with indentation and newlines. Defaults to false. - **:key-fn**: (function) - A function to transform keys before serialization. - **:replacer**: (function) - A function that can filter or transform values during serialization. It receives `key` and `value` and can return `nil` to omit the value, or a new value to serialize. ### Request Example ```lisp ;; Basic serialization to string (jzon:stringify #(1 2 3 "hello" null nil t)) ;; => "[1,2,3,\"hello\",null,false,true]" ;; Pretty print to standard output (jzon:stringify (alexandria:plist-hash-table '("name" "Bob" "score" 95)) :stream t :pretty t) ;; Write to a file (jzon:stringify my-data :stream #p"/path/to/output.json" :pretty t) ;; Serialize a CLOS object (defclass person () ((name :initarg :name) (age :initarg :age) (active :initarg :active :type boolean))) (jzon:stringify (make-instance 'person :name "Carol" :age 25 :active nil) :pretty t :stream t) ;; Use a replacer function to filter/transform values (jzon:stringify #("first" "second" "third") :stream t :pretty t :replacer (lambda (key value) (case key ((nil) t) ; Always include toplevel (0 nil) ; Exclude index 0 (1 t) ; Include index 1 as-is (2 (values t (format nil "Modified: ~A" value)))))) ``` ### Response #### Success Response (200) - **json-string**: (string) - The JSON string representation of the input value. #### Response Example ```lisp ;; For basic serialization to string ;; => "[1,2,3,\"hello\",null,false,true]" ;; For pretty printing to stream ;; Output: ;; { ;; "name": "Bob", ;; "score": 95 ;; } ``` ``` -------------------------------- ### Streaming JSON Parsing with jzon:with-parser Source: https://context7.com/zulu-inuoe/jzon/llms.txt Demonstrates how to create and use a streaming JSON parser for incremental processing. This method is ideal for large JSON files as it avoids loading the entire structure into memory. It supports SAX-like event handling and can parse complete sub-elements. ```lisp ;; Basic streaming parser usage (jzon:with-parser (parser "{\"x\": 1, \"y\": [2, 3]}") (multiple-value-list (jzon:parse-next parser)) ; => (:BEGIN-OBJECT NIL) (multiple-value-list (jzon:parse-next parser)) ; => (:OBJECT-KEY "x") (multiple-value-list (jzon:parse-next parser)) ; => (:VALUE 1) (multiple-value-list (jzon:parse-next parser)) ; => (:OBJECT-KEY "y") (multiple-value-list (jzon:parse-next parser)) ; => (:BEGIN-ARRAY NIL) (multiple-value-list (jzon:parse-next parser)) ; => (:VALUE 2) (multiple-value-list (jzon:parse-next parser)) ; => (:VALUE 3) (multiple-value-list (jzon:parse-next parser)) ; => (:END-ARRAY NIL) (multiple-value-list (jzon:parse-next parser)) ; => (:END-OBJECT NIL) (multiple-value-list (jzon:parse-next parser))) ; => (NIL NIL) - done ;; Read a complete sub-element during streaming (jzon:with-parser (p "{ \"items\": [1, 2, 3], \"count\": 3 }") (jzon:parse-next p) ; :begin-object (jzon:parse-next p) ; :object-key "items" (jzon:parse-next-element p) ; => #(1 2 3) - reads entire array (jzon:parse-next p) ; :object-key "count" (jzon:parse-next p)) ; :value 3 ;; Process large file streaming (jzon:with-parser (parser #p"/path/to/large.json" :allow-comments t :max-string-length 1000000) (loop for event = (jzon:parse-next parser) while event do (format t "Event: ~A~%" event))) ``` -------------------------------- ### Jzon Custom Serialization Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Information on customizing JSON serialization for types not covered by default mappings. ```APIDOC ## Custom Serialization ### Description When using `jzon:stringify` or `jzon:write-value`, you can customize the writing of values not covered in the default Type Mappings. ### Customization Method The call graph for customization involves `jzon:write-value` calling `(method standard-object)` which can then invoke `jzon:coerced-fields`. ### Standard Object Serialization By default, `standard-object` instances are serialized as JSON objects. Each **bound** slot of the object is used as a key in the JSON object. #### Slot Type Handling for `nil` Values The `:type` specified for a slot influences how a `nil` value in that slot is serialized: 1. **`boolean`**: `nil` serializes as `false`. 2. **`list`**: `nil` serializes as `[]` (an empty array). 3. **`null`**: `nil` serializes as `null`. **Note**: If a slot's type is unspecified, `nil` will serialize as `null` by default. ``` -------------------------------- ### jzon: Error Handling for JSON Operations (Common Lisp) Source: https://context7.com/zulu-inuoe/jzon/llms.txt Illustrates how to handle various JSON-related errors using Common Lisp's `handler-case`. This includes catching parsing errors, limit exceeded errors (depth/length), and write errors like circular references. ```lisp ;; Handle parsing errors (handler-case (jzon:parse "{ invalid json }") (jzon:json-parse-error (e) (format t "Parse error: ~A~%" e)) (jzon:json-eof-error (e) (format t "Unexpected end of input: ~A~%" e))) ;; Handle depth/length limit errors (handler-case (jzon:parse "[[[[[[[[[[]]]]]]]]]]" :max-depth 5) (jzon:json-parse-limit-error (e) (format t "Limit exceeded: ~A~%" e))) ;; Handle write errors (handler-case (let ((circular (list 1 2 3))) (setf (cdr (last circular)) circular) ; Make circular (jzon:stringify circular)) (jzon:json-recursive-write-error (e) (format t "Circular reference detected: ~A~%" e))) ;; Condition hierarchy: ;; jzon:json-error (base) ;; jzon:json-parse-error ;; jzon:json-parse-limit-error ;; jzon:json-eof-error ;; jzon:json-write-error ;; jzon:json-write-limit-error ;; jzon:json-recursive-write-error ``` -------------------------------- ### Custom Serialization with jzon:write-value Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Demonstrates how to specialize the jzon:write-value generic function to handle custom object serialization, providing specific JSON output based on object properties. ```APIDOC ## Specializing jzon:write-value ### Description This allows for custom serialization by emitting specific values for a given object. The `jzon:write-value` generic function can be specialized for custom classes. ### Method `defmethod jzon:write-value (writer (job job)) (cond ((string= (company job) "WISE") (jzon:write-object writer "company" "Eastern Healthcare" "title" (aref #("Psychologist" "Physician" "Janitor" "Surgeon" "Receptionist") (random 5)))) ((string= (title job) "Assassin") (jzon:with-object writer (jzon:write-properties writer "company" "City Hall" "title" "Clerk") (jzon:write-key writer "lifelines") (jzon:write-array writer "Yuri" "Camilla"))) ((string= (company job) "State Police") (jzon:write-string "Classified")) (t #| Allow default to take over |# (call-next-method)))) ### Request Example ```lisp (jzon:stringify (make-instance 'job :company "WISE" :title "Agent") :stream t :pretty t) ``` ### Response Example ```json { "company": "Eastern Healthcare", "title": "Psychologist" } ``` ### Request Example ```lisp (jzon:stringify (make-instance 'job :company "The Butcher" :title "Assassin") :stream t :pretty t) ``` ### Response Example ```json { "company": "City Hall", "title": "Clerk", "lifelines": [ "Yuri", "Camilla" ] } ``` ### Request Example ```lisp (jzon:stringify (make-instance 'job :company "State Police" :title "Interrogator") :stream t :pretty t) ``` ### Response Example ```json "Classified" ``` ``` -------------------------------- ### Jzon Object Writing Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Functions and macros for writing JSON objects using the Jzon library. ```APIDOC ## Jzon Object Writing ### Description Functions and macros for writing JSON objects using the Jzon library. ### Functions * `jzon:begin-object writer` - Begin writing an object. * `json:end-object writer` - Finish writing an object. * `jzon:with-object writer` - Open a block where you can begin writing object properties. * `jzon:write-key writer key` - Write an object key. * `json:write-property writer key value` - Write an object key and value. * `jzon:write-properties writer &rest key* value*` - Write several object keys and values. * `jzon:write-object writer &rest key* value*` - Open a new object, write its keys and values, and close it. ### Examples **Using begin-object and end-object:** ```lisp (jzon:begin-object*) (jzon:write-property* "age" 42) (jzon:end-object*) ``` **Using with-object:** ```lisp (jzon:with-object* (jzon:write-property* "age" 42)) ``` **Using write-key and write-value:** ```lisp (jzon:with-object* (jzon:write-key* "age") (jzon:write-value* 42)) ``` **Using write-properties:** ```lisp (jzon:with-object* (jzon:write-properties* "age" 42 "colour" "blue" "x" 0 "y" 10)) ``` **Using write-object:** ```lisp (jzon:write-object* "age" 42 "colour" "blue" "x" 0 "y" 10) ``` ``` -------------------------------- ### Jzon Array Writing Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Functions and macros for writing JSON arrays using the Jzon library. ```APIDOC ## Jzon Array Writing ### Description Functions and macros for writing JSON arrays using the Jzon library. ### Functions * `jzon:begin-array writer` - Begin writing an array. * `json:end-array writer` - Finish writing an array. * `jzon:with-array writer` - Open a block to begin writing array values. * `jzon:write-values writer &rest values*` - Write several array values. * `jzon:write-array` - Open a new array, write its values, and close it. ### Examples **Using begin-array and end-array:** ```lisp (jzon:begin-array*) (jzon:write-value* 0) (jzon:write-value* 1) (jzon:write-value* 2) (jzon:end-array*) ``` **Using with-array:** ```lisp (jzon:with-array* (jzon:write-value* 0) (jzon:write-value* 1) (jzon:write-value* 2)) ``` **Using write-values within with-array:** ```lisp (jzon:with-array* (jzon:write-values* 0 1 2)) ``` **Using write-array:** ```lisp (jzon:write-array* 0 1 2) ``` ``` -------------------------------- ### Create a JSON Parser with jzon:make-parser (Lisp) Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Describes the jzon:make-parser function, which creates a JSON parser instance. It details the various input types for the JSON source (string, vector, stream, pathname, span) and configuration options like allowing comments, trailing commas, multiple content, max string length, and key transformation. ```lisp ;; Example usage (conceptual, actual usage depends on context) ;; (jzon:make-parser "{\"key\": \"value\"}" :allow-comments t) ``` -------------------------------- ### Custom JSON Parsing with jzon:with-parser Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Explains the use of jzon:with-parser for advanced control over the parsing process, particularly useful for avoiding the consing of large amounts of user-supplied data and for implementing custom parsing logic. ```common-lisp (jzon:with-parser (lambda (parser input) ...) (jzon:parse input)) ``` -------------------------------- ### Serialize Common Lisp values to a pretty-printed JSON string Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Illustrates serializing a Common Lisp vector containing various data types into a JSON string using `jzon:stringify`. The `:stream t` and `:pretty t` arguments ensure the output is formatted for readability. ```lisp (jzon:stringify #(null nil t 42 3.14 "Hello, world!") :stream t :pretty t) ``` -------------------------------- ### SAX-like JSON Parsing with jzon:with-parser (Lisp) Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Illustrates the SAX-like streaming API of jzon:parser by using jzon:with-parser to process a JSON string incrementally. It shows how jzon:parse-next emits events and values as it traverses the JSON structure. ```lisp (jzon:with-parser (parser "{\"x\": 1, \"y\": [2, 3], \"live\": false}") (jzon:parse-next parser) #| :begin-object |# (jzon:parse-next parser) #| :object-key, "x" |# (jzon:parse-next parser) #| :value, 1 |# (jzon:parse-next parser) #| :object-key, "y" |# (jzon:parse-next parser) #| :begin-array |# (jzon:parse-next parser) #| :value, 2 |# (jzon:parse-next parser) #| :value, 3 |# (jzon:parse-next parser) #| :end-array |# (jzon:parse-next parser) #| :object-key, "live" |# (jzon:parse-next parser) #| :value, nil |# (jzon:parse-next parser) #| :end-object |# (jzon:parse-next parser)) #| nil |# ``` -------------------------------- ### Write JSON Object and Arrays using jzon:writer API (Lisp) Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Demonstrates using the `jzon:writer` API in Lisp to construct a JSON object with nested arrays. It showcases functions like `jzon:with-object*`, `jzon:write-key*`, `jzon:write-value*`, `jzon:write-property*`, `jzon:write-properties*`, `jzon:with-array*`, `jzon:write-values*`, and `jzon:write-array*` for detailed JSON generation. ```lisp (jzon:with-writer* (:stream *standard-output* :pretty t) (jzon:with-object* (jzon:write-key* :age) (jzon:write-value* 24) (jzon:write-property* :colour :blue) (jzon:write-properties* :outside nil :interests #() :talent 'null) (jzon:write-key* "an-array") (jzon:with-array* (jzon:write-values* :these :are :elements)) (jzon:write-key* "another array") (jzon:write-array* :or "you" "can use this"))) ``` -------------------------------- ### jzon:write-value - Custom JSON Serialization (Common Lisp) Source: https://context7.com/zulu-inuoe/jzon/llms.txt Demonstrates how to define custom JSON representations for user-defined types using the `jzon:write-value` generic function. This allows for specialized serialization logic, such as converting a timestamp to an ISO 8601 string or a point object to a JSON array. ```lisp ;; Custom serialization for a timestamp type (defclass timestamp () ((unix-time :initarg :unix-time :reader unix-time))) (defmethod jzon:write-value ((writer jzon:writer) (ts timestamp)) ;; Write timestamp as ISO 8601 string (jzon:write-value writer (multiple-value-bind (sec min hour day month year) (decode-universal-time (unix-time ts) 0) (format nil "~4,'0D-~2,'0D-~2,'0DT~2,'0D:~2,'0D:~2,'0DZ" year month day hour min sec)))) (jzon:stringify (make-instance 'timestamp :unix-time (get-universal-time)) :stream t) ;; => "2024-01-15T10:30:45Z" ;; Custom serialization that outputs a different JSON structure (defclass point () ((x :initarg :x) (y :initarg :y) (z :initarg :z))) (defmethod jzon:write-value ((writer jzon:writer) (p point)) ;; Write as array instead of object (jzon:write-array writer (slot-value p 'x) (slot-value p 'y) (slot-value p 'z))) (jzon:stringify (make-instance 'point :x 1 :y 2 :z 3) :stream t) ;; => [1,2,3] ``` -------------------------------- ### jzon:parse function signature and parameters Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Provides the function signature and detailed explanation of parameters for `jzon:parse`. This function is used for reading JSON data and accepts various input types and parsing options. ```lisp * jzon:parse * in &key max-depth allow-comments allow-trailing-comma allow-multiple-content max-string-length key-fn *=> value* * *in* - a `string`, `vector (unsigned-byte 8)`, `stream`, `pathname`, or [`jzon:span`](#jzonspan) * *max-depth* - a positive `integer`, or a boolean * *allow-comments* - a `boolean` * *allow-trailing-comma* - a `boolean` * *allow-multiple-content* - a `boolean` * *max-string-length* - `nil`, `t`, or a positive `integer` * *key-fn* - a designator for a function of one argument, or a boolean *value* - a `jzon:json-element` (see [Type Mappings](#type-mappings)) ``` -------------------------------- ### Parse JSON string into Common Lisp values Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Demonstrates parsing a JSON string into Common Lisp data structures using `jzon:parse`. It shows how JSON types like null, boolean, number, string, array, and object are mapped to their Common Lisp equivalents (symbols, vectors, hash-tables). ```lisp (defparameter *ht* (jzon:parse "{ \"license\": null, \"active\": false, \"important\": true, \"id\": 1, \"xp\": 3.2, \"name\": \"Rock\", \"tags\": [ \"alone\" ] }")) (equalp 'null (gethash "licence" *ht*)) (equalp nil (gethash "active" *ht*)) (equalp t (gethash "important" *ht*)) (equalp 1 (gethash "id" *ht*)) (equalp 3.2d0 (gethash "xp" *ht*)) (equalp "Rock" (gethash "name" *ht*)) (equalp #("alone") (gethash "tags" *ht*)) ``` -------------------------------- ### jzon:parse Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Parses JSON data from various input sources into Common Lisp values. Supports various options for flexibility and safety. ```APIDOC ## jzon:parse ### Description Parses JSON data from various input sources into Common Lisp values. Supports various options for flexibility and safety. ### Method `FUNCTION` ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None * **in** (*string*, *vector (unsigned-byte 8)*, *stream*, *pathname*, or *jzon:span*) - Input source for JSON data. * **max-depth** (*integer* or *boolean*) - Maximum nesting depth for parsing. Defaults to a reasonable value. * **allow-comments** (*boolean*) - Whether to allow C-style comments in the JSON input. Defaults to `nil`. * **allow-trailing-comma** (*boolean*) - Whether to allow trailing commas in JSON arrays and objects. Defaults to `nil`. * **allow-multiple-content** (*boolean*) - Whether to allow multiple JSON documents in a single input stream. Defaults to `nil`. * **max-string-length** (*nil*, *t*, or *integer*) - Maximum allowed length for JSON strings. Defaults to a reasonable value. * **key-fn** (*function designator* or *boolean*) - Function to process keys in JSON objects. If `t`, keys are interned symbols. Defaults to `nil`. ### Request Example ```lisp (jzon:parse "{ \"key\": \"value\" }") ``` ### Response #### Success Response (200) * **value** (*jzon:json-element*) - The parsed Common Lisp representation of the JSON data. #### Response Example ```json { "key": "value" } ``` ``` -------------------------------- ### Stringifying Common Lisp objects to JSON with jzon Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Illustrates how to use jzon:stringify to convert standard Common Lisp data structures into JSON formatted strings. This function is designed to produce reasonable JSON output from typical CL objects without requiring custom data structures. ```common-lisp (jzon:stringify '(:a 1 :b "hello")) (jzon:stringify '(1 2 (3 4))) (jzon:stringify nil) ``` -------------------------------- ### jzon:parse-next Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Reads and returns the next JSON event and its associated value from the parser. ```APIDOC ### jzon:parse-next *Function* **jzon:parse-next** *parser* *=> event, value* * *event* - a symbol, see below * *value* - a `jzon:json-atom` #### Description Reads and returns the next JSON event and its associated value from the parser. ``` -------------------------------- ### jzon:stringify Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Serializes Common Lisp values into a JSON string. Supports various options for output formatting and additional type mappings. ```APIDOC ## jzon:stringify ### Description Serializes Common Lisp values into a JSON string. Supports various options for output formatting and additional type mappings. ### Method `FUNCTION` ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None * **value** - The Common Lisp value to serialize. * **:stream** (*boolean*) - Whether to write the output to a stream. Defaults to `nil`. * **:pretty** (*boolean*) - Whether to format the output with indentation for readability. Defaults to `nil`. * **:indent** (*string*) - The string to use for indentation when `:pretty` is `t`. Defaults to two spaces. * **:max-depth** (*integer*) - Maximum nesting depth for serialization. Defaults to a reasonable value. ### Request Example ```lisp (jzon:stringify #(1 2 3) :pretty t) ``` ### Response #### Success Response (200) * **json-string** (*string*) - The JSON string representation of the input value. #### Response Example ```json [ 1, 2, 3 ] ``` ``` -------------------------------- ### jzon:close-parser Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Closes the parser and releases any associated resources. ```APIDOC ### jzon:close-parser *Function* **jzon:close-parser** *parser* *=> parser* * *parser* - a [`jzon:parser`](#jzonparser) #### Description Closes the parser and releases any held resources. ``` -------------------------------- ### Manage JSON Parser Lifecycle with jzon:with-parser (Lisp) Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Introduces the jzon:with-parser macro, which simplifies the management of a jzon:parser's lifecycle. It automatically handles the creation of the parser using jzon:make-parser and ensures it is closed using jzon:close-parser via an unwind-protect mechanism, similar to with-open-file. ```lisp ;; Example usage: ;; (jzon:with-parser (parser "{\"key\": \"value\"}") ;; (jzon:parse-next parser)) ``` -------------------------------- ### jzon:writer Source: https://github.com/zulu-inuoe/jzon/blob/develop/README.md Provides an interface for streaming JSON output. Useful for large JSON structures or when direct string construction is inefficient. ```APIDOC ## jzon:writer ### Description Provides an interface for streaming JSON output. Useful for large JSON structures or when direct string construction is inefficient. ### Method `INTERFACE` ### Endpoint N/A ### Parameters None directly for the interface, but functions like `jzon:with-writer`, `jzon:write-value`, and others operate on writers. ### Request Example ```lisp (with-output-to-string (s) (jzon:with-writer s :pretty t :indent " ") (jzon:write-value "hello" :stream s) (jzon:write-value 123 :stream s)) ``` ### Response #### Success Response (200) * **Output** - The streamed JSON output. #### Response Example ```json "hello" 123 ``` ```