7.2. Boost package for JSON

The JSON_BOOST module extends JSON support with operator overloads for convenient field access (?[]), null-coalescing (??), and automatic struct-to-JSON conversion macros (from_JsValue, to_JsValue).

See also JSON manipulation library for core JSON parsing and writing. See JSON for a hands-on tutorial.

All functions and symbols are in “json_boost” module, use require to get access to it.

require daslib/json_boost

Example:

require daslib/json_boost

    [export]
    def main() {
        let data = "\{ \"name\": \"Alice\", \"age\": 30 \}"
        var error = ""
        var js <- read_json(data, error)
        if (error == "") {
            let name = js?.name ?? "?"
            print("name = {name}\n")
            let age = js?.age ?? -1
            print("age = {age}\n")
        }
        unsafe {
            delete js
        }
    }
    // output:
    // name = Alice
    // age = 30

7.2.1. Field annotations

Struct fields can carry annotations that control how JV / from_JV and the builtin sprint_json serialize and deserialize them. Annotations are parsed by parse_json_annotation into a JsonFieldState and stored in a static_let cache so each field is parsed only once.

sprint_json requires options rtti for annotations to take effect at runtime.

Annotation

Effect

@optional

Skip the field when its value is default / empty (0, false, empty string, empty array, empty table, null pointer).

@rename="json_key"

Use json_key instead of the daslang field name in JSON output and when looking up keys during from_JV deserialization. The annotation value must be a string (@rename="name"). A bare @rename with no string value is silently ignored.

@embed

Treat a string field as raw JSON — embed it without extra quoting. During JV conversion the string is parsed with read_json and the resulting sub-tree is inserted directly.

@unescape

Write the string field without escaping special characters (backslashes, quotes, etc.).

@enum_as_int

Serialize an enum field as its integer value instead of the enumeration name string.

Example with sprint_json:

options rtti

struct Config {
    name : string
    @optional debug : bool          // omitted when false
    @rename="type" _type : string   // JSON key is "type"
    @embed raw : string             // embedded as raw JSON
    @unescape path : string         // no escaping of backslashes
    @enum_as_int level : Priority   // integer, not string
}

let json_str = sprint_json(cfg, false)

See JSON for runnable examples of every annotation.

7.2.1.1. Structures

json_boost::JsonFieldState

Per-field serialization options for JSON struct conversion.

Fields
  • argName : string - name of the field in JSON

  • enumAsInt : bool - whether to parse enum as integer

  • unescape : bool - whether to unescape strings

  • embed : bool - whether to embed the field

  • optional : bool - whether the field is optional

7.2.1.2. Reader macros

json_boost::json

This macro implements embedding of the JSON object into the program:

var jsv = %json~
{
  "name": "main_window",
  "value": 500,
  "size": [1,2,3]
} %%

7.2.1.3. Variant macros

json_boost::better_json

This macro is used to implement is json_value and as json_value runtime checks. It essentially substitutes value as name with value.value as name and value is name with value.value is name.

7.2.1.4. Value conversion

7.2.1.4.1. JV

json_boost::JV(val1: auto; val2: auto; val3: auto; val4: auto; val5: auto; val6: auto; val7: auto; val8: auto; val9: auto) : JsonValue?()

Creates array of nine JsonValues.

Arguments
  • val1 : auto

  • val2 : auto

  • val3 : auto

  • val4 : auto

  • val5 : auto

  • val6 : auto

  • val7 : auto

  • val8 : auto

  • val9 : auto

json_boost::JV(val1: auto; val2: auto; val3: auto; val4: auto) : JsonValue?()
json_boost::JV(val1: auto; val2: auto; val3: auto; val4: auto; val5: auto; val6: auto; val7: auto) : JsonValue?()
json_boost::JV(val1: auto; val2: auto; val3: auto; val4: auto; val5: auto; val6: auto; val7: auto; val8: auto; val9: auto; val10: auto) : JsonValue?()
json_boost::JV(val1: auto; val2: auto; val3: auto; val4: auto; val5: auto; val6: auto) : JsonValue?()
json_boost::JV(val1: auto; val2: auto; val3: auto; val4: auto; val5: auto) : JsonValue?()
json_boost::JV(val1: auto; val2: auto) : JsonValue?()
json_boost::JV(val1: auto; val2: auto; val3: auto; val4: auto; val5: auto; val6: auto; val7: auto; val8: auto) : JsonValue?()
json_boost::JV(val1: auto; val2: auto; val3: auto) : JsonValue?()
json_boost::JV(v: auto(VecT)) : auto()
json_boost::JV(value: auto(TT)) : JsonValue?()

7.2.1.4.2. from_JV

json_boost::from_JV(v: JsonValue const?; ent: uint16; defV: uint16 = uint16(0)) : auto()

Parse a JSON value and return the corresponding native value.

Arguments
json_boost::from_JV(v: JsonValue const?; ent: uint8; defV: uint8 = uint8(0)) : auto()
json_boost::from_JV(v: JsonValue const?; ent: int8; defV: int8 = int8(0)) : auto()
json_boost::from_JV(v: JsonValue const?; ent: int16; defV: int16 = int16(0)) : auto()
json_boost::from_JV(v: JsonValue const?; ent: bitfield; defV: bitfield = bitfield()) : auto()
json_boost::from_JV(v: JsonValue const?; ent: uint; defV: uint = 0x0) : auto()
json_boost::from_JV(v: JsonValue const?; ent: int; defV: int = 0) : auto()
json_boost::from_JV(v: JsonValue const?; ent: bitfield16:uint16<>; defV: bitfield16 = bitfield16()) : auto()
json_boost::from_JV(v: JsonValue const?; ent: auto(VecT); defV: VecT = VecT()) : auto()
json_boost::from_JV(v: JsonValue const?; ent: bitfield64:uint64<>; defV: bitfield64 = bitfield64()) : auto()
json_boost::from_JV(v: JsonValue const?; anything: auto(TT)) : auto()
json_boost::from_JV(v: JsonValue const?; anything: table<auto(KT), auto(VT)>) : auto()
json_boost::from_JV(v: JsonValue const?; ent: int64; defV: int64 = 0) : auto()
json_boost::from_JV(v: JsonValue const?; ent: float; defV: float = 0f) : auto()
json_boost::from_JV(v: JsonValue const?; ent: string; defV: string = "") : auto()
json_boost::from_JV(v: JsonValue const?; ent: auto(EnumT); defV: EnumT = EnumT()) : EnumT()
json_boost::from_JV(v: JsonValue const?; ent: bool; defV: bool = false) : auto()
json_boost::from_JV(v: JsonValue const?; ent: double; defV: double = 0lf) : auto()
json_boost::from_JV(v: JsonValue const?; ent: uint64; defV: uint64 = 0x0) : auto()
json_boost::from_JV(v: JsonValue const?; ent: bitfield8:uint8<>; defV: bitfield8 = bitfield8()) : auto()

7.2.1.5. Element access operators

JsonValue const? ==const?.(a: JsonValue const? ==const; key: string) : JsonValue?()

Returns the value of the key in the JSON object, if it exists.

Arguments

7.2.1.5.1. JsonValue const? ==const?[]

json_boost::JsonValue const? ==const?[](a: JsonValue const? ==const; key: string) : JsonValue?()

Returns the value of the key in the JSON object, if it exists.

Arguments
json_boost::JsonValue const? ==const?[](a: JsonValue const? ==const; idx: int) : JsonValue?()

JsonValue? ==const?.(a: JsonValue? ==const; key: string) : JsonValue?()

Returns the value of the key in the JSON object, if it exists.

Arguments

7.2.1.5.2. JsonValue? ==const?[]

json_boost::JsonValue? ==const?[](a: JsonValue? ==const; idx: int) : JsonValue?()

Returns the value of the index in the JSON array, if it exists.

Arguments
json_boost::JsonValue? ==const?[](a: JsonValue? ==const; key: string) : JsonValue?()

7.2.1.6. Null coalescing operators

7.2.1.6.1. JsonValue const???

json_boost::JsonValue const???(a: JsonValue const?; val: float) : float()

Returns the value of the JSON object, if it exists, otherwise returns the default value.

Arguments
json_boost::JsonValue const???(a: JsonValue const?; val: double) : double()
json_boost::JsonValue const???(a: JsonValue const?; val: int16) : int16()
json_boost::JsonValue const???(a: JsonValue const?; val: int8) : int8()
json_boost::JsonValue const???(a: JsonValue const?; val: uint8) : uint8()
json_boost::JsonValue const???(a: JsonValue const?; val: int64) : int64()
json_boost::JsonValue const???(a: JsonValue const?; val: uint16) : uint16()
json_boost::JsonValue const???(a: JsonValue const?; val: int) : int()
json_boost::JsonValue const???(a: JsonValue const?; val: bool) : bool()
json_boost::JsonValue const???(a: JsonValue const?; val: uint64) : uint64()
json_boost::JsonValue const???(a: JsonValue const?; val: uint) : uint()
json_boost::JsonValue const???(a: JsonValue const?; val: string) : string()

7.2.1.7. Value extraction

JsonValue const? ==const?.`value(a: JsonValue const? ==const) : variant<_object:table<string;JsonValue?>;_array:array<JsonValue?>;_string:string;_number:double;_longint:int64;_bool:bool;_null:void?> const?()

Returns the value of the JSON object, if it exists.

Arguments
JsonValue? ==const?.`value(a: JsonValue? ==const) : variant<_object:table<string;JsonValue?>;_array:array<JsonValue?>;_string:string;_number:double;_longint:int64;_bool:bool;_null:void?>?()

Returns the value of the JSON object, if it exists.

Arguments

7.2.1.8. Annotation parsing

json_boost::parse_json_annotation(name: string; annotation: array<tuple<name:string;data:variant<tBool:bool;tInt:int;tUInt:uint;tInt64:int64;tUInt64:uint64;tFloat:float;tDouble:double;tString:string;nothing:any>>>) : JsonFieldState()

Parse JSON field annotations and return the corresponding JsonFieldState.

Arguments
  • name : string

  • annotation : array<tuple<name:string;data: RttiValue>>