Skip to content

Commit

Permalink
Add a "JsonElement" reader
Browse files Browse the repository at this point in the history
  • Loading branch information
atifaziz committed Dec 11, 2022
1 parent 00b5b4c commit fbc71e6
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/JsonReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,30 @@ bool TryReadItem(ReadOnlySpan<byte> span,
}
}

static IJsonReader<JsonElement>? jsonElementReader;

public static IJsonReader<JsonElement> Element() =>
jsonElementReader ??=
Create(static (ref Utf8JsonReader rdr) =>
{
ref var inner = ref Utf8JsonReader.GetInnerReader(ref rdr);
#if NET6_0_OR_GREATER
return JsonElement.TryParseValue(ref inner, out var element)
? JsonReadResult.Value(element.Value)
: JsonReadError.Incomplete;
#elif NETCOREAPP3_1_OR_GREATER
if (!JsonDocument.TryParseValue(ref inner, out var doc))
return JsonReadError.Incomplete;
using var _ = doc;
return JsonReadResult.Value(doc.RootElement.Clone());
#else
#error Unsupported platform.
#endif
});


public static IJsonReader<T> Error<T>(string message) =>
CreatePure<T>((ref Utf8JsonReader _) => Error(message));

Expand Down
2 changes: 2 additions & 0 deletions src/Utf8JsonReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public ref struct Utf8JsonReader
System.Text.Json.Utf8JsonReader reader;
Stack<object>? stack;

public static ref System.Text.Json.Utf8JsonReader GetInnerReader(ref Utf8JsonReader reader) => ref reader.reader;

public Utf8JsonReader(ReadOnlySpan<byte> jsonData, JsonReaderOptions options = default) :
this(new(jsonData, options), stack: null) { }

Expand Down
46 changes: 46 additions & 0 deletions tests/JsonReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1051,4 +1051,50 @@ public void Let_Returns_Select_That_Receives_Reader_Return()
Assert.NotNull(result);
Assert.Same(outputReader, result);
}

[Theory]
[InlineData(/*lang=json*/ "null")]
[InlineData(/*lang=json*/ "false")]
[InlineData(/*lang=json*/ "true")]
[InlineData(/*lang=json*/ "-4.2")]
[InlineData(/*lang=json*/ """ "foobar" """)]
[InlineData(/*lang=json*/ "[1, 2, 3]")]
[InlineData(/*lang=json*/ """
{
"null": null,
"true": true,
"false": false,
"number": 12345.67890,
"string": "The quick brown fox jumps over the lazy dog.",
"array": [],
"object": {}
}
""")]
public void Element_With_Valid_Input(string json)
{
var actual = JsonReader.Element().Read(json);
var reader = new System.Text.Json.Utf8JsonReader(Encoding.UTF8.GetBytes(json));
#if NET6_0_OR_GREATER
var expected = JsonElement.ParseValue(ref reader);
#elif NETCOREAPP3_1_OR_GREATER
using var doc = JsonDocument.ParseValue(ref reader);
var expected = doc.RootElement.Clone();
#else
#error Unsupported platform.
#endif
Assert.Equal(expected.ToString(), actual.ToString());
}

[Theory]
[InlineData(/*lang=json*/ "null")]
[InlineData(/*lang=json*/ "false")]
[InlineData(/*lang=json*/ "true")]
[InlineData(/*lang=json*/ "-4.2")]
[InlineData(/*lang=json*/ """ "foobar" """)]
[InlineData(/*lang=json*/ "[]")]
[InlineData(/*lang=json*/ "{}")]
public void Element_Moves_Reader(string json)
{
TestReaderPositionPostRead(JsonReader.Element(), json);
}
}

0 comments on commit fbc71e6

Please # to comment.