json/encode
typeclass for serializing a Turmeric value to a JSON
(encode-json 42) ;; => "42" (encode-json "hi") ;; => "\"hi\"" (encode-json true) ;; => "true"
Since: P2a (minimal slice, 2026-06-12)
encode-json-string
(encode-json-string [^EncodeJson A])
serialize any Encodable value to an owned String.
| x | any value whose type has an EncodeJson instance |
String -- owned serialized JSON.
(let [s (encode-json-string 42)] ... (release s)) ;; owned "42"
Since: 0.3.0
decode-json-list
(decode-json-list [A])
decode a JSON array into a `(Cons A)`, the mirror of
Since: U2 (Track C container instances)
derive-json
(derive-json [type-name & fields])
emit an `EncodeJson` instance for a `defstruct` product
(defstruct User [id : int name : cstr active : bool])
(derive-json User (id int) (name cstr) (active bool))
;; (encode-json (make-struct User 7 "alice" true))
;; => {"id":7,"name":"alice","active":true}
derive-json-encode
(derive-json-encode [type-name & fields])
emit only the EncodeJson instance for a defstruct,
(defstruct LogEntry [level : cstr msg : cstr])
(derive-json-encode LogEntry (level cstr) (msg cstr))
;; (encode-json (make-struct LogEntry "info" "hi"))
;; => {"level":"info","msg":"hi"}
derive-json-decode
(derive-json-decode [type-name & fields])
emit only the DecodeJson instance for a defstruct,
(defstruct Config [port : int host : cstr])
(derive-json-decode Config (port int) (host cstr))
;; (:: (decode-json doc root) (Result Config cstr))
;; parses {"port":8080,"host":"localhost"} into a Config.
derive-json-opaque
(derive-json-opaque [type-name _as carrier])
emit EncodeJson + DecodeJson instances for a `defopaque`
(defopaque UserId :int) (derive-json-opaque UserId :as int) ;; (encode-json (:: 42 UserId)) => "42" ;; (:: (decode-json doc val) (Result UserId cstr)) => parses int as UserId Carriers supported: any type with `EncodeJson` / `DecodeJson` instances -- `int`, `bool`, `cstr`, `float` ship in this module; user-defined carriers work if their instances are in scope at the derive site.
derive-json-opaque-encode
(derive-json-opaque-encode [type-name _as carrier])
emit only the EncodeJson instance for a
derive-json-opaque-decode
(derive-json-opaque-decode [type-name _as carrier])
emit only the DecodeJson instance for a
derive-json-sum-encode
(derive-json-sum-encode [type-name & ctors])
emit only the `EncodeJson` instance for a
derive-json-sum-decode
(derive-json-sum-decode [type-name & ctors])
emit only the `DecodeJson` instance for a `defdata`
derive-json-sum
(derive-json-sum [type-name & ctors])
emit both EncodeJson and DecodeJson instances for a `defdata`
(defdata Event :copy [] (Click :int :int) (Scroll :int))
(derive-json-sum Event (Click (x int) (y int)) (Scroll (dy int)))
;; (encode-json (Click 3 4)) => {"Click":{"x":3,"y":4}}
;; (:: (decode-json doc root) (Result Event cstr)) parses it back
Limitations (carried from the struct slice):
- Field-name policy is identity; `:rename-fields` not honored yet.
- Inner field decode does not accumulate structured errors yet.
- Nullary constructors encode as `{"Ctor":{}}` (empty inner object).
JsonDecodeErrors
(JsonDecodeErrors)
opaque handle to an accumulated list of decode violations.
json-decode-errors-count
(json-decode-errors-count [e : JsonDecodeErrors] :)
JsonDecodeErrors reporting surface.
json-decode-error-path
(json-decode-error-path [e : JsonDecodeErrors i : int] :)
the object key of the i-th violation.
json-decode-error-expected
(json-decode-error-expected [e : JsonDecodeErrors i : int] :)
the expected JSON type of the i-th violation.
json-decode-error-got
(json-decode-error-got [e : JsonDecodeErrors i : int] :)
the JSON type actually seen for the i-th violation.
json-decode-errors-free
(json-decode-errors-free [e : JsonDecodeErrors] :)
release the accumulator and its owned strings.
derive-json-decoder
(derive-json-decoder [type-name & fields])
emit a `DecodeJsonChecked` instance for a `defstruct` of
(defstruct Person [name : cstr age : int])
(derive-json-decoder Person (name cstr) (age int))
;; (:: (decode-json-checked doc root) (Result Person JsonDecodeErrors))
;; {"name":"al","age":30} => (ok <Person>)
;; {"name":123} => (err <2 violations: name/string/int, age/int/missing>)
Limitations (v1): primitive fields only (nested objects / arrays are a
follow-up), field paths are the bare key (no dot-nesting yet), and the
field cap follows `__decode-make-struct` (<=5). For richer shapes, hand-write
the DecodeJsonChecked instance.
Internal definitions
EncodeJson[int]-- decimal integer.EncodeJson[bool]-- the literals "true" / "false". The returned bufferEncodeJson[cstr]-- JSON string literal: surrounded by `"`, with theEncodeJson[float]-- a JSON number for an IEEE-754 double. The mirror of__json-null-frag-- the JSON `null` literal as a fresh malloc'd cstr, soEncodeJson[Option]-- a present value encodes as its element's fragment; an__json-arr-build__json-arr-fragsEncodeJson[Cons]-- a homogeneous list `(Cons A)` encodes as a JSON array, each__json-obj-build__json-tag__json-chainDecodeJson[int]-- read the value at `val` as a 64-bit integer. AcceptsDecodeJson[cstr]-- read the value at `val` as a JSON string. Returns aDecodeJson[bool]-- accept JSON `true` / `false` only. Rejects numbers,DecodeJson[float]-- read the value at `val` as an IEEE-754 double. Accepts__json-absent?-- true when a value slot is missing (null handle, e.g. aDecodeJson[Option]-- a missing slot or JSON `null` decodes to `none`; anything__json-is-arr?-- true when the value is a JSON array.__json-arr-size-- element count of a JSON array value.__json-arr-get-- the i-th element value of a JSON array, as a yyjson_val__json-arr-decode__decode-field__decode-fields__decode-make-structEncodeJson[]DecodeJson[]EncodeJson[]DecodeJson[]__sum-fnames__sum-vchain__sum-enc-arms__sum-dfields__sum-dec-armsEncodeJson[]DecodeJson[]__errs-new__errs-push__errs-count__errs-path__errs-expected__errs-got__errs-free__jtype-name__jis-int?__jis-str?__jis-bool?__jis-num?__check-int__check-cstr__check-bool__check-float__derive-checks