dlang-community / std_data_json

Phobos candidate JSON implementation.
25 stars 13 forks source link

readObject without allocating for each key? #54

Open Panke opened 3 years ago

Panke commented 3 years ago

stdx.data.json.parser.readObject issues a callback for each key in an object. The type for the callback is scope void delegate(string key) @safe del).

For my use case it would be sufficient to get the raw key string, e.g. use a delegate with type void delegate(JSONString!String key) to safe on allocations and unescaping the string. The next best solution would be to avoid string and get a const(char)[] as a key. Currently I cannot do this:

void main()
{
    const(char)[] json = q{{"key": "val"}}.dup;
    auto nodes = parseJSONStream!(LexOptions.useLong, const(char)[])(json);

    void delegate(const (char)[] k) @safe del = (const(char)[] x) { writeln("x"); };
    nodes.readObject(del);
}

Error: delegate del(string key) is not callable using argument types (const(char)[])

Looking at the code, a possible work around would be.

  1. cast the input to immutable (although it isn't)
  2. use string throughout, the lexing code will not allocate if the input is immutable and does not need unescaping
  3. be careful to cast everything back / correctly handle the immutable values that aren't.

It will still check if the keys are escaped, although I don't need that. Thinking about it, maybe it's enough to change the signature to void delegate(String key) and also provide a slice if the buffer is not immutable, but const.

What do you think?