Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Handle unmaterialize set endings in UTF8FaunaReader #201

Merged
merged 1 commit into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions Fauna.Test/Serialization/Utf8FaunaReader.Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -593,4 +593,30 @@ public void SkipNestedArrays()
Assert.AreEqual(TokenType.FieldName, reader.CurrentTokenType);
Assert.AreEqual("k2", reader.GetString());
}

[Test]
public void HandlesUnmaterializedSets()
{
const string test =
@"{""products"":{""@set"":""hdWCxmdQcm9kdWN0gcqEamJ5Q2F0ZWdvcnmBxmJ2MPT2gc1KBbkdRAugBgAEAvbBghpnGCOgGjW0K0AQ""},""name"":""foo""}";
var reader = new Utf8FaunaReader(test);
reader.Read(); // {
Assert.AreEqual(TokenType.StartObject, reader.CurrentTokenType);
reader.Read(); // "products"
Assert.AreEqual(TokenType.FieldName, reader.CurrentTokenType);
Assert.AreEqual("products", reader.GetString());
reader.Read(); // { "@set":
Assert.AreEqual(TokenType.StartPage, reader.CurrentTokenType);
reader.Read(); // "hdWCxmdQcm9kdWN0gcqEamJ5Q2F0ZWdvcnmBxmJ2MPT2gc1KBbkdRAugBgAEAvbBghpnGCOgGjW0K0AQ"
Assert.AreEqual("hdWCxmdQcm9kdWN0gcqEamJ5Q2F0ZWdvcnmBxmJ2MPT2gc1KBbkdRAugBgAEAvbBghpnGCOgGjW0K0AQ", reader.GetString());
reader.Read(); // "}"
Assert.AreEqual(TokenType.EndPage, reader.CurrentTokenType);
reader.Read(); // "name"
Assert.AreEqual(TokenType.FieldName, reader.CurrentTokenType);
Assert.AreEqual("name", reader.GetString());
reader.Read(); // "foo"
Assert.AreEqual("foo", reader.GetString());
reader.Read(); // "}"
Assert.AreEqual(TokenType.EndObject, reader.CurrentTokenType);
}
}
20 changes: 19 additions & 1 deletion Fauna/Serialization/Utf8FaunaReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public ref struct Utf8FaunaReader
private Utf8JsonReader _json;
private readonly Stack<object> _tokenStack = new();
private TokenType? _bufferedTokenType = null;
private object? _bufferedTokenValue = null;

private readonly HashSet<TokenType> _closers = new()
{
Expand All @@ -37,6 +38,7 @@ private enum TokenTypeInternal
{
/// <summary>The token type is the start of an escaped Fauna object.</summary>
StartEscapedObject,
StartPageUnmaterialized,
}

/// <summary>
Expand Down Expand Up @@ -106,6 +108,9 @@ public bool Read()
return true;
}

// At this point we're passed a buffered token type so this read should unset this no matter what
_bufferedTokenValue = null;

if (!Advance())
{
return false;
Expand Down Expand Up @@ -188,6 +193,7 @@ public bool Read()

try
{
if (_bufferedTokenValue != null) return (string)_bufferedTokenValue;
return _json.GetString();
}
catch (Exception e)
Expand Down Expand Up @@ -598,7 +604,16 @@ private void HandleStartObject()
case "@set":
AdvanceTrue();
CurrentTokenType = TokenType.StartPage;
_tokenStack.Push(TokenType.StartPage);
if (_json.TokenType == JsonTokenType.String)
{
_bufferedTokenValue = _json.GetString();
_bufferedTokenType = TokenType.String;
_tokenStack.Push(TokenTypeInternal.StartPageUnmaterialized);
}
else
{
_tokenStack.Push(TokenType.StartPage);
}
break;
case "@time":
HandleTaggedString(TokenType.Time);
Expand Down Expand Up @@ -636,6 +651,9 @@ private void HandleEndObject()
CurrentTokenType = TokenType.EndPage;
AdvanceTrue();
break;
case TokenTypeInternal.StartPageUnmaterialized:
CurrentTokenType = TokenType.EndPage;
break;
case TokenType.StartRef:
CurrentTokenType = TokenType.EndRef;
AdvanceTrue();
Expand Down
Loading