.. _stdlib_json_boost: ====================== Boost package for JSON ====================== .. das:module:: json_boost 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 :doc:`json` for core JSON parsing and writing. See :ref:`tutorial_json` for a hands-on tutorial. All functions and symbols are in "json_boost" module, use require to get access to it. .. code-block:: das require daslib/json_boost Example: .. code-block:: das 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 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 :ref:`parse_json_annotation ` into a :ref:`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. .. list-table:: :header-rows: 1 :widths: 20 80 * - 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``: .. code-block:: das 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 :ref:`tutorial_json` for runnable examples of every annotation. ++++++++++ Structures ++++++++++ .. _struct-json_boost-JsonFieldState: .. das:attribute:: 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 +++++++++++++ Reader macros +++++++++++++ .. _call-macro-json_boost-json: .. das:attribute:: json This macro implements embedding of the JSON object into the program:: var jsv = %json~ { "name": "main_window", "value": 500, "size": [1,2,3] } %% ++++++++++++++ Variant macros ++++++++++++++ .. _call-macro-json_boost-better_json: .. das:attribute:: 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`. ++++++++++++++++ Value conversion ++++++++++++++++ * :ref:`JV (val1: auto; val2: auto; val3: auto; val4: auto; val5: auto; val6: auto; val7: auto; val8: auto; val9: auto) : JsonValue? ` * :ref:`JV (val1: auto; val2: auto; val3: auto; val4: auto) : JsonValue? ` * :ref:`JV (val1: auto; val2: auto; val3: auto; val4: auto; val5: auto; val6: auto; val7: auto) : JsonValue? ` * :ref:`JV (val1: auto; val2: auto; val3: auto; val4: auto; val5: auto; val6: auto; val7: auto; val8: auto; val9: auto; val10: auto) : JsonValue? ` * :ref:`JV (val1: auto; val2: auto; val3: auto; val4: auto; val5: auto; val6: auto) : JsonValue? ` * :ref:`JV (val1: auto; val2: auto; val3: auto; val4: auto; val5: auto) : JsonValue? ` * :ref:`JV (val1: auto; val2: auto) : JsonValue? ` * :ref:`JV (val1: auto; val2: auto; val3: auto; val4: auto; val5: auto; val6: auto; val7: auto; val8: auto) : JsonValue? ` * :ref:`JV (val1: auto; val2: auto; val3: auto) : JsonValue? ` * :ref:`JV (v: auto(VecT)) : auto ` * :ref:`JV (value: auto(TT)) : JsonValue? ` * :ref:`from_JV (v: JsonValue const?; ent: uint16; defV: uint16 = uint16(0)) : auto ` * :ref:`from_JV (v: JsonValue const?; ent: uint8; defV: uint8 = uint8(0)) : auto ` * :ref:`from_JV (v: JsonValue const?; ent: int8; defV: int8 = int8(0)) : auto ` * :ref:`from_JV (v: JsonValue const?; ent: int16; defV: int16 = int16(0)) : auto ` * :ref:`from_JV (v: JsonValue const?; ent: bitfield; defV: bitfield = bitfield()) : auto ` * :ref:`from_JV (v: JsonValue const?; ent: uint; defV: uint = 0x0) : auto ` * :ref:`from_JV (v: JsonValue const?; ent: int; defV: int = 0) : auto ` * :ref:`from_JV (v: JsonValue const?; ent: bitfield16:uint16\<\>; defV: bitfield16 = bitfield16()) : auto ` * :ref:`from_JV (v: JsonValue const?; ent: auto(VecT); defV: VecT = VecT()) : auto ` * :ref:`from_JV (v: JsonValue const?; ent: bitfield64:uint64\<\>; defV: bitfield64 = bitfield64()) : auto ` * :ref:`from_JV (v: JsonValue const?; anything: auto(TT)) : auto ` * :ref:`from_JV (v: JsonValue const?; anything: table\) : auto ` * :ref:`from_JV (v: JsonValue const?; ent: int64; defV: int64 = 0) : auto ` * :ref:`from_JV (v: JsonValue const?; ent: float; defV: float = 0f) : auto ` * :ref:`from_JV (v: JsonValue const?; ent: string; defV: string = "") : auto ` * :ref:`from_JV (v: JsonValue const?; ent: auto(EnumT); defV: EnumT = EnumT()) : EnumT ` * :ref:`from_JV (v: JsonValue const?; ent: bool; defV: bool = false) : auto ` * :ref:`from_JV (v: JsonValue const?; ent: double; defV: double = 0lf) : auto ` * :ref:`from_JV (v: JsonValue const?; ent: uint64; defV: uint64 = 0x0) : auto ` * :ref:`from_JV (v: JsonValue const?; ent: bitfield8:uint8\<\>; defV: bitfield8 = bitfield8()) : auto ` JV ^^ .. _function-json_boost_JV_auto_auto_auto_auto_auto_auto_auto_auto_auto_0x2cc: .. das:function:: 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 .. _function-json_boost_JV_auto_auto_auto_auto_0x2b3: .. das:function:: JV(val1: auto; val2: auto; val3: auto; val4: auto) : JsonValue? .. _function-json_boost_JV_auto_auto_auto_auto_auto_auto_auto_0x2c2: .. das:function:: JV(val1: auto; val2: auto; val3: auto; val4: auto; val5: auto; val6: auto; val7: auto) : JsonValue? .. _function-json_boost_JV_auto_auto_auto_auto_auto_auto_auto_auto_auto_auto_0x2d1: .. das:function:: JV(val1: auto; val2: auto; val3: auto; val4: auto; val5: auto; val6: auto; val7: auto; val8: auto; val9: auto; val10: auto) : JsonValue? .. _function-json_boost_JV_auto_auto_auto_auto_auto_auto_0x2bd: .. das:function:: JV(val1: auto; val2: auto; val3: auto; val4: auto; val5: auto; val6: auto) : JsonValue? .. _function-json_boost_JV_auto_auto_auto_auto_auto_0x2b8: .. das:function:: JV(val1: auto; val2: auto; val3: auto; val4: auto; val5: auto) : JsonValue? .. _function-json_boost_JV_auto_auto_0x2a9: .. das:function:: JV(val1: auto; val2: auto) : JsonValue? .. _function-json_boost_JV_auto_auto_auto_auto_auto_auto_auto_auto_0x2c7: .. das:function:: JV(val1: auto; val2: auto; val3: auto; val4: auto; val5: auto; val6: auto; val7: auto; val8: auto) : JsonValue? .. _function-json_boost_JV_auto_auto_auto_0x2ae: .. das:function:: JV(val1: auto; val2: auto; val3: auto) : JsonValue? .. _function-json_boost_JV_autoVecT_0x17d: .. das:function:: JV(v: auto(VecT)) : auto .. _function-json_boost_JV_autoTT_0x223: .. das:function:: JV(value: auto(TT)) : JsonValue? ---- from_JV ^^^^^^^ .. _function-json_boost_from_JV_JsonValue_const_q__uint16_uint16: .. das:function:: from_JV(v: JsonValue const?; ent: uint16; defV: uint16 = uint16(0)) : auto Parse a JSON value and return the corresponding native value. :Arguments: * **v** : :ref:`JsonValue `? * **ent** : uint16 * **defV** : uint16 .. _function-json_boost_from_JV_JsonValue_const_q__uint8_uint8: .. das:function:: from_JV(v: JsonValue const?; ent: uint8; defV: uint8 = uint8(0)) : auto .. _function-json_boost_from_JV_JsonValue_const_q__int8_int8: .. das:function:: from_JV(v: JsonValue const?; ent: int8; defV: int8 = int8(0)) : auto .. _function-json_boost_from_JV_JsonValue_const_q__int16_int16: .. das:function:: from_JV(v: JsonValue const?; ent: int16; defV: int16 = int16(0)) : auto .. _function-json_boost_from_JV_JsonValue_const_q__bitfield_bitfield: .. das:function:: from_JV(v: JsonValue const?; ent: bitfield; defV: bitfield = bitfield()) : auto .. _function-json_boost_from_JV_JsonValue_const_q__uint_uint: .. das:function:: from_JV(v: JsonValue const?; ent: uint; defV: uint = 0x0) : auto .. _function-json_boost_from_JV_JsonValue_const_q__int_int: .. das:function:: from_JV(v: JsonValue const?; ent: int; defV: int = 0) : auto .. _function-json_boost_from_JV_JsonValue_const_q__bitfield16_c_uint16_ls__gr__bitfield16: .. das:function:: from_JV(v: JsonValue const?; ent: bitfield16:uint16<>; defV: bitfield16 = bitfield16()) : auto .. _function-json_boost_from_JV_JsonValue_const_q__autoVecT_VecT_0x189: .. das:function:: from_JV(v: JsonValue const?; ent: auto(VecT); defV: VecT = VecT()) : auto .. _function-json_boost_from_JV_JsonValue_const_q__bitfield64_c_uint64_ls__gr__bitfield64: .. das:function:: from_JV(v: JsonValue const?; ent: bitfield64:uint64<>; defV: bitfield64 = bitfield64()) : auto .. _function-json_boost_from_JV_JsonValue_const_q__autoTT_0x1ca: .. das:function:: from_JV(v: JsonValue const?; anything: auto(TT)) : auto .. _function-json_boost_from_JV_JsonValue_const_q__table_ls_autoKT,_autoVT_gr_: .. das:function:: from_JV(v: JsonValue const?; anything: table) : auto .. _function-json_boost_from_JV_JsonValue_const_q__int64_int64: .. das:function:: from_JV(v: JsonValue const?; ent: int64; defV: int64 = 0) : auto .. _function-json_boost_from_JV_JsonValue_const_q__float_float: .. das:function:: from_JV(v: JsonValue const?; ent: float; defV: float = 0f) : auto .. _function-json_boost_from_JV_JsonValue_const_q__string_string: .. das:function:: from_JV(v: JsonValue const?; ent: string; defV: string = "") : auto .. _function-json_boost_from_JV_JsonValue_const_q__autoEnumT_EnumT_0xf6: .. das:function:: from_JV(v: JsonValue const?; ent: auto(EnumT); defV: EnumT = EnumT()) : EnumT .. _function-json_boost_from_JV_JsonValue_const_q__bool_bool: .. das:function:: from_JV(v: JsonValue const?; ent: bool; defV: bool = false) : auto .. _function-json_boost_from_JV_JsonValue_const_q__double_double: .. das:function:: from_JV(v: JsonValue const?; ent: double; defV: double = 0lf) : auto .. _function-json_boost_from_JV_JsonValue_const_q__uint64_uint64: .. das:function:: from_JV(v: JsonValue const?; ent: uint64; defV: uint64 = 0x0) : auto .. _function-json_boost_from_JV_JsonValue_const_q__bitfield8_c_uint8_ls__gr__bitfield8: .. das:function:: from_JV(v: JsonValue const?; ent: bitfield8:uint8<>; defV: bitfield8 = bitfield8()) : auto ++++++++++++++++++++++++ Element access operators ++++++++++++++++++++++++ * :ref:`JsonValue const? ==const?. (a: JsonValue const? ==const; key: string) : JsonValue? ` * :ref:`JsonValue const? ==const?[] (a: JsonValue const? ==const; key: string) : JsonValue? ` * :ref:`JsonValue const? ==const?[] (a: JsonValue const? ==const; idx: int) : JsonValue? ` * :ref:`JsonValue? ==const?. (var a: JsonValue? ==const; key: string) : JsonValue? ` * :ref:`JsonValue? ==const?[] (var a: JsonValue? ==const; idx: int) : JsonValue? ` * :ref:`JsonValue? ==const?[] (var a: JsonValue? ==const; key: string) : JsonValue? ` .. _function-json_boost__q__dot__JsonValue_const_q___eq__eq_const_string: .. das:function:: JsonValue const? ==const?.(a: JsonValue const? ==const; key: string) : JsonValue? Returns the value of the key in the JSON object, if it exists. :Arguments: * **a** : :ref:`JsonValue `?! * **key** : string JsonValue const? ==const?[] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. _function-json_boost__q__lb__rb__JsonValue_const_q___eq__eq_const_string: .. das:function:: JsonValue const? ==const?[](a: JsonValue const? ==const; key: string) : JsonValue? Returns the value of the key in the JSON object, if it exists. :Arguments: * **a** : :ref:`JsonValue `?! * **key** : string .. _function-json_boost__q__lb__rb__JsonValue_const_q___eq__eq_const_int: .. das:function:: JsonValue const? ==const?[](a: JsonValue const? ==const; idx: int) : JsonValue? ---- .. _function-json_boost__q__dot___JsonValue_q___eq__eq_const_string: .. das:function:: JsonValue? ==const?.(a: JsonValue? ==const; key: string) : JsonValue? Returns the value of the key in the JSON object, if it exists. :Arguments: * **a** : :ref:`JsonValue `?! * **key** : string JsonValue? ==const?[] ^^^^^^^^^^^^^^^^^^^^^ .. _function-json_boost__q__lb__rb___JsonValue_q___eq__eq_const_int: .. das:function:: JsonValue? ==const?[](a: JsonValue? ==const; idx: int) : JsonValue? Returns the value of the index in the JSON array, if it exists. :Arguments: * **a** : :ref:`JsonValue `?! * **idx** : int .. _function-json_boost__q__lb__rb___JsonValue_q___eq__eq_const_string: .. das:function:: JsonValue? ==const?[](a: JsonValue? ==const; key: string) : JsonValue? +++++++++++++++++++++++++ Null coalescing operators +++++++++++++++++++++++++ * :ref:`JsonValue const??? (a: JsonValue const?; val: float) : float ` * :ref:`JsonValue const??? (a: JsonValue const?; val: double) : double ` * :ref:`JsonValue const??? (a: JsonValue const?; val: int16) : int16 ` * :ref:`JsonValue const??? (a: JsonValue const?; val: int8) : int8 ` * :ref:`JsonValue const??? (a: JsonValue const?; val: uint8) : uint8 ` * :ref:`JsonValue const??? (a: JsonValue const?; val: int64) : int64 ` * :ref:`JsonValue const??? (a: JsonValue const?; val: uint16) : uint16 ` * :ref:`JsonValue const??? (a: JsonValue const?; val: int) : int ` * :ref:`JsonValue const??? (a: JsonValue const?; val: bool) : bool ` * :ref:`JsonValue const??? (a: JsonValue const?; val: uint64) : uint64 ` * :ref:`JsonValue const??? (a: JsonValue const?; val: uint) : uint ` * :ref:`JsonValue const??? (a: JsonValue const?; val: string) : string ` JsonValue const??? ^^^^^^^^^^^^^^^^^^ .. _function-json_boost__q__q__JsonValue_const_q__float: .. das:function:: JsonValue const???(a: JsonValue const?; val: float) : float Returns the value of the JSON object, if it exists, otherwise returns the default value. :Arguments: * **a** : :ref:`JsonValue `? * **val** : float .. _function-json_boost__q__q__JsonValue_const_q__double: .. das:function:: JsonValue const???(a: JsonValue const?; val: double) : double .. _function-json_boost__q__q__JsonValue_const_q__int16: .. das:function:: JsonValue const???(a: JsonValue const?; val: int16) : int16 .. _function-json_boost__q__q__JsonValue_const_q__int8: .. das:function:: JsonValue const???(a: JsonValue const?; val: int8) : int8 .. _function-json_boost__q__q__JsonValue_const_q__uint8: .. das:function:: JsonValue const???(a: JsonValue const?; val: uint8) : uint8 .. _function-json_boost__q__q__JsonValue_const_q__int64: .. das:function:: JsonValue const???(a: JsonValue const?; val: int64) : int64 .. _function-json_boost__q__q__JsonValue_const_q__uint16: .. das:function:: JsonValue const???(a: JsonValue const?; val: uint16) : uint16 .. _function-json_boost__q__q__JsonValue_const_q__int: .. das:function:: JsonValue const???(a: JsonValue const?; val: int) : int .. _function-json_boost__q__q__JsonValue_const_q__bool: .. das:function:: JsonValue const???(a: JsonValue const?; val: bool) : bool .. _function-json_boost__q__q__JsonValue_const_q__uint64: .. das:function:: JsonValue const???(a: JsonValue const?; val: uint64) : uint64 .. _function-json_boost__q__q__JsonValue_const_q__uint: .. das:function:: JsonValue const???(a: JsonValue const?; val: uint) : uint .. _function-json_boost__q__q__JsonValue_const_q__string: .. das:function:: JsonValue const???(a: JsonValue const?; val: string) : string ++++++++++++++++ Value extraction ++++++++++++++++ * :ref:`JsonValue const? ==const?.value (a: JsonValue const? ==const) : variant\<_object:table\;_array:array\;_string:string;_number:double;_longint:int64;_bool:bool;_null:void?\> const? ` * :ref:`JsonValue? ==const?.value (var a: JsonValue? ==const) : variant\<_object:table\;_array:array\;_string:string;_number:double;_longint:int64;_bool:bool;_null:void?\>? ` .. _function-json_boost__q__dot__rq_value_JsonValue_const_q___eq__eq_const: .. das:function:: JsonValue const? ==const?.value(a: JsonValue const? ==const) : variant<_object:table;_array:array;_string:string;_number:double;_longint:int64;_bool:bool;_null:void?> const? Returns the value of the JSON object, if it exists. :Arguments: * **a** : :ref:`JsonValue `?! .. _function-json_boost__q__dot__rq_value__JsonValue_q___eq__eq_const: .. das:function:: JsonValue? ==const?.value(a: JsonValue? ==const) : variant<_object:table;_array:array;_string:string;_number:double;_longint:int64;_bool:bool;_null:void?>? Returns the value of the JSON object, if it exists. :Arguments: * **a** : :ref:`JsonValue `?! ++++++++++++++++++ Annotation parsing ++++++++++++++++++ * :ref:`parse_json_annotation (name: string; annotation: array\\>\>) : JsonFieldState ` .. _function-json_boost_parse_json_annotation_string_array_ls_tuple_ls_name_c_string;data_c_variant_ls_tBool_c_bool;tInt_c_int;tUInt_c_uint;tInt64_c_int64;tUInt64_c_uint64;tFloat_c_float;tDouble_c_double;tString_c_string;nothing_c_any_gr__gr__gr_: .. das:function:: parse_json_annotation(name: string; annotation: array>>) : JsonFieldState Parse JSON field annotations and return the corresponding JsonFieldState. :Arguments: * **name** : string * **annotation** : array`>>