1 module text.json.ParserMarker;
2 
3 import funkwerk.stdx.data.json.lexer;
4 import funkwerk.stdx.data.json.parser;
5 import meta.never;
6 import std.json;
7 import std.typecons;
8 import text.json.Decode;
9 import text.json.JsonValueRange;
10 
11 /**
12  * This magic type represents an offset into a JSON parser input stream.
13  * While parsing a message, a value of this type is skipped.
14  * Later on, it can be parsed into a (now better known) type.
15  */
16 struct ParserMarker
17 {
18     alias StringStream = typeof(parseJSONStream!(LexOptions.noTrackLocation)(""));
19     alias JsonStream = JsonValueRange;
20 
21     private Nullable!StringStream stringStream;
22 
23     private Nullable!JsonStream jsonStream;
24 
25     invariant (this.stringStream.isNull != this.jsonStream.isNull);
26 
27     public this(StringStream stringStream)
28     {
29         this.stringStream = stringStream.nullable;
30     }
31 
32     public this(JsonStream jsonStream)
33     {
34         this.jsonStream = jsonStream.nullable;
35     }
36 
37     public this(JSONValue value)
38     {
39         this.jsonStream = JsonStream(value).nullable;
40     }
41 
42     public T decode(T, alias transform = never)() const
43     {
44         import std.typecons: Yes;
45 
46         if (!this.stringStream.isNull)
47         {
48             StringStream stream = this.stringStream.get.dup;
49 
50             return decodeJson!(T, transform, Yes.logErrors)(stream, T.stringof);
51         }
52         else
53         {
54             JsonStream stream = this.jsonStream.get.dup;
55 
56             return decodeJson!(T, transform, Yes.logErrors)(stream, T.stringof);
57         }
58     }
59 }