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 }