Skip to content

ddn.data.json5

Working, copy-pastable examples for ddn.data.json5.

The ddn.data.json5 module provides a JSON5 parser and writer that maps values to and from ddn.var. JSON5 is a superset of JSON that supports comments, trailing commas, unquoted keys, single-quoted strings, and a richer set of numeric literals.

Parse JSON5 into var

This example parses a JSON5 document containing comments, trailing commas, unquoted keys, and single quotes.

/+ dub.sdl:
    name "json5-parse-basic"
    dependency "ddn" path="../.."
+/
import ddn.data.json5 : parseJSON5, Json5Error;
import ddn.var : var;
import std.stdio : writeln;

void main() {
    var v;
    Json5Error err;

    auto text = q{
        // JSON5 allows comments
        {
            unquotedKey: 123,
            quotedKey: "hello",
            singleQuoted: 'world',
            trailing: [1, 2, 3,],
        }
    };

    if (!parseJSON5(v, text, err)) {
        writeln("Parse failed at offset ", err.offset, ": ", err.message);
        return;
    }

    writeln("unquotedKey = ", v["unquotedKey"].as!long);
    writeln("quotedKey   = ", v["quotedKey"].as!string);
    writeln("singleQuoted= ", v["singleQuoted"].as!string);
    writeln("trailing[2] = ", v["trailing"][2].as!long);
}

Minify JSON5 (strip comments and whitespace)

minify is useful when you want to remove comments and formatting while preserving the JSON5 surface syntax.

/+ dub.sdl:
    name "json5-minify"
    dependency "ddn" path="../.."
+/
import ddn.data.json5 : minify;
import std.stdio : writeln;

void main() {
    auto input = "{ a: 1, // comment\n b: 2, }";
    auto compact = minify(input);
    writeln(compact);

    // Expected: comments/whitespace removed, trailing comma preserved.
    assert(compact == "{a:1,b:2,}");
}

Serialize var to JSON5 vs strict JSON

The writer can emit either JSON5 (toJSON5) or strict JSON (toJSON).

/+ dub.sdl:
    name "json5-write"
    dependency "ddn" path="../.."
+/
import ddn.data.json5 : toJSON5, toJSON;
import ddn.var : var;
import std.stdio : writeln;

void main() {
    var v;
    v["a"] = 1;
    v["b"] = "x";

    // JSON5 may omit quotes around identifier keys.
    auto json5Text = toJSON5(v);
    writeln("JSON5: ", json5Text);
    assert(json5Text == "{a:1,b:\"x\"}");

    // Strict JSON always quotes keys and uses JSON escaping.
    auto jsonText = toJSON(v);
    writeln("JSON : ", jsonText);
    assert(jsonText == "{\"a\":1,\"b\":\"x\"}");
}

Error handling with Json5Error

When parsing fails, parseJSON5 returns false and fills Json5Error with details.

/+ dub.sdl:
    name "json5-error-handling"
    dependency "ddn" path="../.."
+/
import ddn.data.json5 : parseJSON5, Json5Error;
import ddn.var : var;
import std.stdio : writeln;

void main() {
    var v;
    Json5Error err;

    // Missing closing brace.
    if (!parseJSON5(v, "{a:1", err)) {
        writeln("Parse error code: ", err.code);
        writeln("Offset          : ", err.offset);
        writeln("Message         : ", err.message);
        assert(err.offset > 0);
    } else {
        assert(false);
    }
}

Pretty printing

Use Json5WriteOptions to enable formatting.

/+ dub.sdl:
    name "json5-pretty"
    dependency "ddn" path="../.."
+/
import ddn.data.json5 : toJSON5, Json5WriteOptions;
import ddn.var : var;
import std.stdio : writeln;

void main() {
    var v;
    v["name"] = "dejan";
    v["nums"] = [1, 2, 3];

    Json5WriteOptions o = Json5WriteOptions.init;
    o.pretty = true;
    o.indentWidth = 2;

    auto text = toJSON5(v, o);
    writeln(text);
    assert(text.length > 0);
}