Report a bug
If you spot a problem with this page, click here to create a GitHub issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

mir.ion.ser.json

High level JSON serialization API

struct JsonSerializer(string sep, Appender);
JSON serialization back-end
Appender* appender;
JSON string buffer
int serdeTarget;
Mutable value used to choose format specidied or user-defined serialization specializations
size_t stringBegin();
void putStringPart(scope const(char)[] value);
Puts string part. The implementation allows to split string unicode points.
void stringEnd(size_t);
size_t structBegin(size_t length = 0);
void structEnd(size_t state);
size_t listBegin(size_t length = 0);
void listEnd(size_t state);
alias sexpBegin = listBegin;
alias sexpEnd = listEnd;
alias annotationsBegin = listBegin;
void putSymbol(scope const char[] symbol);
void putAnnotation(scope const(char)[] annotation);
void annotationsEnd(size_t state);
size_t annotationWrapperBegin();
alias annotationWrapperEnd = structEnd;
void nextTopLevelValue();
void putCompiletimeKey(string key)();
void putKey(scope const char[] key);
void putValue(Num)(const Num value)
if (isNumeric!Num && !is(Num == enum));
void putValue(W, WordEndian endian)(BigIntView!(W, endian) view);
void putValue(size_t size)(auto ref const BigInt!size num);
void putValue(size_t size)(auto ref const Decimal!size num);
void putValue(typeof(null));

void putNull(IonTypeCode code);
void putValue(bool b);
void putValue(scope const char[] value);
void putValue(Clob value);
void putValue(Blob value);
void putValue(Timestamp value);
void elemBegin();
alias sexpElemBegin = elemBegin;
string serializeJson(V)(auto ref V value, int serdeTarget = SerdeTarget.json);
JSON serialization function.
Examples:
struct S
{
    string foo;
    uint bar;
}

assert(serializeJson(S("str", 4)) == `{"foo":"str","bar":4}`);
Examples:
import mir.serde: serdeIgnoreDefault;

static struct Decor
{
    int candles; // 0
    float fluff = float.infinity; // inf 
}

static struct Cake
{
    @serdeIgnoreDefault
    string name = "Chocolate Cake";
    int slices = 8;
    float flavor = 1;
    @serdeIgnoreDefault
    Decor dec = Decor(20); // { 20, inf }
}

assert(Cake("Normal Cake").serializeJson == `{"name":"Normal Cake","slices":8,"flavor":1.0}`);
auto cake = Cake.init;
cake.dec = Decor.init;
assert(cake.serializeJson == `{"slices":8,"flavor":1.0,"dec":{"candles":0,"fluff":"+inf"}}`);
assert(cake.dec.serializeJson == `{"candles":0,"fluff":"+inf"}`);

static struct A
{
    @serdeIgnoreDefault
    string str = "Banana";
    int i = 1;
}
assert(A.init.serializeJson == `{"i":1}`);

static struct S
{
    @serdeIgnoreDefault
    A a;
}
assert(S.init.serializeJson == `{}`);
assert(S(A("Berry")).serializeJson == `{"a":{"str":"Berry","i":1}}`);

static struct D
{
    S s;
}
assert(D.init.serializeJson == `{"s":{}}`);
assert(D(S(A("Berry"))).serializeJson == `{"s":{"a":{"str":"Berry","i":1}}}`);
assert(D(S(A(null, 0))).serializeJson == `{"s":{"a":{"str":"","i":0}}}`);

static struct F
{
    D d;
}
assert(F.init.serializeJson == `{"d":{"s":{}}}`);
Examples:
import mir.serde: serdeIgnoreIn;

static struct S
{
    @serdeIgnoreIn
    string s;
}
// assert(`{"s":"d"}`.deserializeJson!S.s == null, `{"s":"d"}`.deserializeJson!S.s);
assert(S("d").serializeJson == `{"s":"d"}`);
Examples:
import mir.ion.deser.json;

static struct S
{
    @serdeIgnoreOut
    string s;
}
assert(`{"s":"d"}`.deserializeJson!S.s == "d");
assert(S("d").serializeJson == `{}`);
Examples:
import mir.serde: serdeIgnoreOutIf;

static struct S
{
    @serdeIgnoreOutIf!`a < 0`
    int a;
}

assert(serializeJson(S(3)) == `{"a":3}`, serializeJson(S(3)));
assert(serializeJson(S(-3)) == `{}`);
Examples:
import mir.rc.array;
auto ar = rcarray!int(1, 2, 4);
assert(ar.serializeJson == "[1,2,4]");
Examples:
import mir.ndslice.topology: iota;
import mir.serde: serdeIgnoreOut, serdeLikeList, serdeProxy;
import std.array: Appender;

static struct S
{
    private int count;
    @serdeLikeList
    auto numbers() @property // uses `foreach`
    {
        return iota(count);
    }

    @serdeLikeList
    @serdeProxy!string // input element type of
    @serdeIgnoreOut
    Appender!(string[]) strings; //`put` method is used
}

assert(S(5).serializeJson == `{"numbers":[0,1,2,3,4]}`);
// assert(`{"strings":["a","b"]}`.deserializeJson!S.strings.data == ["a","b"]);
Examples:
import mir.serde: serdeLikeStruct, serdeProxy;

static struct M
{
    private int sum;

    // opApply is used for serialization
    int opApply(int delegate(scope const char[] key, ref const int val) pure @safe dg) pure @safe
    {
        { int var = 1; if (auto r = dg("a", var)) return r; }
        { int var = 2; if (auto r = dg("b", var)) return r; }
        { int var = 3; if (auto r = dg("c", var)) return r; }
        return 0;
    }

    // opIndexAssign for deserialization
    void opIndexAssign(int val, string key) pure
    {
        sum += val;
    }
}

static struct S
{
    @serdeLikeStruct
    @serdeProxy!int
    M obj;
}

assert(S.init.serializeJson == `{"obj":{"a":1,"b":2,"c":3}}`);
// assert(`{"obj":{"a":1,"b":2,"c":9}}`.deserializeJson!S.obj.sum == 12);
Examples:
import mir.ion.deser.json;
import std.range;
import std.algorithm;
import std.conv;

static struct S
{
    @serdeTransformIn!"a += 2"
    @serdeTransformOut!(a =>"str".repeat.take(a).joiner("_").to!string)
    int a;
}

auto s = deserializeJson!S(`{"a":3}`);
assert(s.a == 5);
assert(serializeJson(s) == `{"a":"str_str_str_str_str"}`);
void serializeJson(Appender, V)(ref Appender appender, auto ref V value, int serdeTarget = SerdeTarget.json);
JSON serialization for custom outputt range.
Examples:
import mir.format: stringBuf;
stringBuf buffer;
static struct S { int a; }
serializeJson(buffer, S(4));
assert(buffer.data == `{"a":4}`);
template serializeJsonPretty(string sep = "\x09")
JSON serialization function with pretty formatting and custom output range.
Examples:
static struct S { int a; }
assert(S(4).serializeJsonPretty!"    " ==
q{{
"a": 4
}});
Examples:
import mir.format: stringBuf;
stringBuf buffer;
static struct S { int a; }
serializeJsonPretty!"    "(buffer, S(4));
assert(buffer.data ==
`{
"a": 4
}`);
void serializeJsonPretty(Appender, V)(ref Appender appender, auto ref V value, int serdeTarget = SerdeTarget.json)
if (isOutputRange!(Appender, const(char)[]) && isOutputRange!(Appender, char));
string serializeJsonPretty(V)(auto ref V value, int serdeTarget = SerdeTarget.json);
JSON serialization function with pretty formatting.
template jsonSerializer(string sep = "")
Creates JSON serialization back-end. Use sep equal to "\t" or " " for pretty formatting.
Examples:
import mir.format: stringBuf;
import mir.bignum.integer;

stringBuf buffer;
auto ser = jsonSerializer((()@trusted=>&buffer)(), 3);
auto state0 = ser.structBegin;

    ser.putKey("null");
    ser.putValue(null);

    ser.putKey("array");
    auto state1 = ser.listBegin();
        ser.elemBegin; ser.putValue(null);
        ser.elemBegin; ser.putValue(123);
        ser.elemBegin; ser.putValue(12300000.123);
        ser.elemBegin; ser.putValue("\t");
        ser.elemBegin; ser.putValue("\r");
        ser.elemBegin; ser.putValue("\n");
        ser.elemBegin; ser.putValue(BigInt!2(1234567890));
    ser.listEnd(state1);

ser.structEnd(state0);

assert(buffer.data == `{"null":null,"array":[null,123,1.2300000123e+7,"\t","\r","\n",1234567890]}`, buffer.data);
Examples:
import std.array;
import mir.bignum.integer;

auto app = appender!string;
auto ser = jsonSerializer!"    "(&app);
auto state0 = ser.structBegin;

    ser.putKey("null");
    ser.putValue(null);

    ser.putKey("array");
    auto state1 = ser.listBegin();
        ser.elemBegin; ser.putValue(null);
        ser.elemBegin; ser.putValue(123);
        ser.elemBegin; ser.putValue(12300000.123);
        ser.elemBegin; ser.putValue("\t");
        ser.elemBegin; ser.putValue("\r");
        ser.elemBegin; ser.putValue("\n");
        ser.elemBegin; ser.putValue(BigInt!2("1234567890"));
    ser.listEnd(state1);

ser.structEnd(state0);

assert(app.data ==
`{
"null": null,
"array": [
    null,
    123,
    1.2300000123e+7,
    "\t",
    "\r",
    "\n",
    1234567890
]
}`, app.data);
auto jsonSerializer(Appender)(return Appender* appender, int serdeTarget = SerdeTarget.json);