JSON¶
To use this module, include the following line in your project file:
require engine.format.json_core // or require engine.core
Serialize and deserialize Daslang values to/from JSON strings.
Use to_json to convert any Daslang value (struct, table, array, variant, etc.) to a JSON string,
and from_json to parse a JSON string back into a typed Daslang value.
Usage example:
struct Player {
name : string
score : int
}
let player = Player(name = "Alice", score = 42)
let json = to_json(player)
// json == "{\n \"name\" : \"Alice\",\n \"score\" : 42\n}\n"
var loaded : Player
from_json(json, loaded)
// loaded.name == "Alice", loaded.score == 42
Supported types
Primitives:
bool,int,uint,int64,uint64,float,double,stringStructs (non-class, non-lambda)
array<T>(element type must be serializable)table<string; V>(key must bestring)variant(matched by JSON value type)Bitfields
void?(serialized as JSONnull)
Tuples are not supported and will be skipped silently.
Field annotations
Struct field annotations control serialization behavior:
@rename = "key"Use
keyas the JSON key instead of the field name. Useful when the JSON key is a reserved word in Daslang (e.g.type,default):struct Item { @rename = "type" type_ : string @rename = "default" default_ : int } // Serializes to: {"type": "...", "default": 0}
Variant serialization
On write, the active variant field is serialized as its plain JSON value (not wrapped in an object). On read, the JSON value type is matched against variant field types in declaration order — the first field whose reduced type matches the JSON type is selected:
variant JsonValue {
int64_ : int64
double_ : double
string_ : string
bool_ : bool
null_ : void?
}
struct Input {
@rename = "type"
type_ : string
required : bool
@rename = "default"
default_ : JsonValue
}
// JSON: {"type": "string", "required": true, "default": "hello"}
var input : Input
from_json("{\"type\": \"string\", \"required\": true, \"default\": \"hello\"}", input)
// input.type_ == "string"
// input.default_ is string_
// input.default_ as string_ == "hello"
Type matching rules (JSON type → Daslang variant field type):
JSON number without decimal → matches
int,int64,uint,int8,int16, etc.JSON number with decimal → matches
float,doubleJSON string → matches
stringJSON bool → matches
boolJSON null → matches
void?JSON array → matches
array<T>JSON object → matches
structortable<string; V>
If no field type matches, the variant keeps its default (first field, zero value).
Optional fields with variant
Use a variant with a void? field to represent optional/nullable JSON values.
The void? field matches JSON null and deserialization tries fields in declaration order,
so put void? last to let concrete types take precedence:
variant MaybeInt {
value : int
null_ : void?
}
struct Config {
count : MaybeInt
}
var a : Config
from_json("{\"count\": 42}", a) // a.count is value, a.count as value == 42
from_json("{\"count\": null}", a) // a.count is null_
from_json("{}", a) // a.count is still null_ -- missing key leaves field unchanged
var b : Config
from_json("{}", b) // b.count is value (zero) -- fresh var starts at first field
Skipped fields
Fields are silently skipped during serialization if they are:
privateOf an unsupported type (class instance, lambda, pointer other than
void?,tablewith non-string key)
Missing JSON keys leave the corresponding field unchanged (not reset to zero). Extra JSON keys are ignored on deserialization.
JSON null on a plain string field produces an empty string "".
Functions¶
- from_json(json_str: string; value: any)¶
Deserializes a JSON string into a typed Daslang value.
Supports structs, classes, arrays, tables, variants, and primitive types.
Struct fields annotated with @rename = "key" are matched by the given key.
Variant fields are matched by trying each variant field name in order.
Extra JSON keys are ignored.
Fields missing in the JSON keep the value the destination variable already has. Array elements and table values are created by the deserializer itself and are initialized with the struct’s field initializers (by running the struct’s generated zero-argument constructor), so JSON fields absent on an element read as the declared defaults.
Note
The generated constructor of a struct that is never constructed explicitly in
script code can be removed by dead code elimination - array elements and table
values of such a struct then stay zero-initialized and the field initializers are
lost. Add options always_export_initializer to the module declaring the struct
to keep its constructor alive.
- Arguments:
json_str : string implicit - JSON string to parse
value : any - variable to deserialize into (must be
var, non-const)
Usage example:
options always_export_initializer // keep struct ctors for from_json defaults
struct Layer {
visible : bool = true
opacity : float = 1f
}
struct Doc {
layers : array<Layer>
}
var doc : Doc
from_json("{\"layers\": [{\"opacity\": 0.5}]}", doc)
// doc.layers[0].visible == true (field initializer applied)
// doc.layers[0].opacity == 0.5
var scores : array<int>
from_json("[1, 2, 3]", scores)
var settings : table<string; float>
from_json("{\"volume\": 0.8, \"brightness\": 1.0}", settings)
- to_json(value: any): string¶
Serializes any Daslang value to a JSON string.
Supports structs, classes, arrays, tables, variants, and primitive types.
Struct fields annotated with @rename = "key" use the given key in JSON.
- Arguments:
value : any - any Daslang value to serialize
- Returns:
string - JSON string representation
Usage example:
struct Rect {
x : float
y : float
width : float
height : float
}
let r = Rect(x = 0.0, y = 0.0, width = 100.0, height = 50.0)
let json = to_json(r)
var scores : array<int>
push(scores, 10)
push(scores, 20)
let json2 = to_json(scores) // "[10, 20]"