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.text

High level (text) Ion serialization API

struct TextSerializer(string sep, Appender);
Ion serialization back-end
Appender* appender;
Ion string buffer
size_t structBegin();
void structEnd(size_t state);
size_t listBegin();
void listEnd(size_t state);
size_t sexpBegin();
void sexpEnd(size_t state);
size_t annotationsBegin();
void putAnnotation(scope const(char)[] str);
void putCompiletimeAnnotation(string str)();
void annotationsEnd(size_t state);
size_t annotationWrapperBegin();
void annotationWrapperEnd(size_t pos);
void nextTopLevelValue();
void putCompiletimeKey(string key)();
void putSymbol(scope const char[] key);
void putKey(scope const char[] key);
void putValue(Num)(const Num num)
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();
void sexpElemBegin();
string serializeText(V)(auto ref V value);
Ion serialization function.
Examples:
struct S
{
    string foo;
    uint bar;
}

assert(serializeText(S("str", 4)) == `{foo:"str",bar:4}`, serializeText(S("str", 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").serializeText == `{name:"Normal Cake",slices:8,flavor:1.0}`);
auto cake = Cake.init;
cake.dec = Decor.init;
assert(cake.serializeText == `{slices:8,flavor:1.0,dec:{candles:0,fluff:+inf}}`, cake.serializeText);
assert(cake.dec.serializeText == `{candles:0,fluff:+inf}`);

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

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

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

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

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

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

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

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

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).serializeText == `{numbers:[0,1,2,3,4]}`);
// assert(`{"strings":["a","b"]}`.deserializeText!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.serializeText == `{obj:{a:1,b:2,c:3}}`, S.init.serializeText);
// assert(`{"obj":{a:1,"b":2,"c":9}}`.deserializeText!S.obj.sum == 12);
Examples:
import mir.ion.deser.ion;
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;
}

assert(serializeText(S(5)) == `{a:"str_str_str_str_str"}`);
string serializeTextPretty(string sep = "\x09", V)(auto ref V value);
Ion serialization function with pretty formatting.
Examples:
static struct S { int a; }
assert(S(4).serializeTextPretty!"    " ==
q{{
a: 4
}});
void serializeText(Appender, V)(ref Appender appender, auto ref V value);
Ion serialization for custom outputt range.
Examples:
import mir.format: stringBuf;
stringBuf buffer;
static struct S { int a; }
serializeText(buffer, S(4));
assert(buffer.data == `{a:4}`);
template serializeTextPretty(string sep = "\x09")
Ion serialization function with pretty formatting and custom output range.
Examples:
import mir.format: stringBuf;
stringBuf buffer;
static struct S { int a; }
serializeTextPretty!"    "(buffer, S(4));
assert(buffer.data ==
`{
a: 4
}`);
void serializeTextPretty(Appender, V)(ref Appender appender, auto ref V value)
if (isOutputRange!(Appender, const(char)[]));
template textSerializer(string sep = "")
Creates Ion 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 = textSerializer((()@trusted=>&buffer)());
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 = textSerializer!"    "(&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 textSerializer(Appender)(return Appender* appender);