Skip to content

Commit

Permalink
Merge pull request #127 from fauna/roundtrippable-shorts
Browse files Browse the repository at this point in the history
Roundtrip short and ushort serialization
  • Loading branch information
pnwpedro authored Jul 1, 2024
2 parents 2d42c55 + e46397c commit 392f061
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 0 deletions.
55 changes: 55 additions & 0 deletions Fauna.Test/Serialization/RoundTrip.Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Fauna.Mapping;
using Fauna.Serialization;
using Fauna.Types;
using NUnit.Framework;
using System.Text;
using System.Text.RegularExpressions;

namespace Fauna.Test.Serialization;

[TestFixture]
public class RoundTripTests
{
private static readonly MappingContext ctx = new();

public static string Serialize(object? obj)
{
using var stream = new MemoryStream();
using var writer = new Utf8FaunaWriter(stream);
Serializer.Serialize(ctx, writer, obj);
writer.Flush();
return Encoding.UTF8.GetString(stream.ToArray());
}

public static T Deserialize<T>(string str) where T : notnull
{
var reader = new Utf8FaunaReader(str);
reader.Read();
var obj = Deserializer.Generate<T>(ctx).Deserialize(ctx, ref reader);
if (reader.Read())
{
throw new SerializationException($"Token stream is not exhausted but should be: {reader.CurrentTokenType}");
}

return obj;
}

[Test]
public void RoundTripShort()
{
const short test = 40;
var serialized = Serialize(test);
var deserialized = Deserialize<short>(serialized);
Assert.AreEqual(test, deserialized);
}

[Test]
public void RoundTripUShort()
{
const ushort test = 40;
var serialized = Serialize(test);
var deserialized = Deserialize<ushort>(serialized);
Assert.AreEqual(test, deserialized);
}

}
4 changes: 4 additions & 0 deletions Fauna/Serialization/Deserializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public static class Deserializer
private static readonly CheckedDeserializer<string> _string = new();
private static readonly CheckedDeserializer<int> _int = new();
private static readonly LongDeserializer _long = new();
private static readonly ShortDeserializer _short = new();
private static readonly UShortDeserializer _ushort = new();
private static readonly CheckedDeserializer<double> _double = new();
private static readonly CheckedDeserializer<DateOnly> _dateOnly = new();
private static readonly CheckedDeserializer<DateTime> _dateTime = new();
Expand Down Expand Up @@ -50,6 +52,8 @@ public static IDeserializer Generate(MappingContext context, Type targetType)
{
if (targetType == typeof(object)) return _object;
if (targetType == typeof(string)) return _string;
if (targetType == typeof(short)) return _short;
if (targetType == typeof(ushort)) return _ushort;
if (targetType == typeof(int)) return _int;
if (targetType == typeof(long)) return _long;
if (targetType == typeof(double)) return _double;
Expand Down
24 changes: 24 additions & 0 deletions Fauna/Serialization/NumberDeserializers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,27 @@ public override long Deserialize(MappingContext context, ref Utf8FaunaReader rea
$"Unexpected token while deserializing: {reader.CurrentTokenType}"),
};
}

internal class ShortDeserializer : BaseDeserializer<short>
{
public override short Deserialize(MappingContext context, ref Utf8FaunaReader reader) =>
reader.CurrentTokenType switch
{
TokenType.Int => reader.GetShort(),
TokenType.Long => reader.GetShort(),
_ => throw new SerializationException(
$"Unexpected token while deserializing: {reader.CurrentTokenType}"),
};
}

internal class UShortDeserializer : BaseDeserializer<ushort>
{
public override ushort Deserialize(MappingContext context, ref Utf8FaunaReader reader) =>
reader.CurrentTokenType switch
{
TokenType.Int => reader.GetUnsignedShort(),
TokenType.Long => reader.GetUnsignedShort(),
_ => throw new SerializationException(
$"Unexpected token while deserializing: {reader.CurrentTokenType}"),
};
}
43 changes: 43 additions & 0 deletions Fauna/Serialization/Utf8FaunaReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,40 @@ public int GetInt()
}
}

/// <summary>
/// Retrieves an short value from the current token.
/// </summary>
/// <returns>An short representation of the current token's value.</returns>
public short GetShort()
{
ValidateTaggedTypes(TokenType.Int, TokenType.Long);
try
{
return short.Parse(_taggedTokenValue!);
}
catch (Exception e)
{
throw new SerializationException($"Failed to get short from {_taggedTokenValue}", e);
}
}

/// <summary>
/// Retrieves an unsigned short value from the current token.
/// </summary>
/// <returns>An unsigned short representation of the current token's value.</returns>
public ushort GetUnsignedShort()
{
ValidateTaggedTypes(TokenType.Int, TokenType.Long);
try
{
return ushort.Parse(_taggedTokenValue!);
}
catch (Exception e)
{
throw new SerializationException($"Failed to get ushort from {_taggedTokenValue}", e);
}
}

/// <summary>
/// Retrieves a long value from the current token.
/// </summary>
Expand Down Expand Up @@ -406,6 +440,15 @@ private void ValidateTaggedType(TokenType type)
}
}

private void ValidateTaggedTypes(params TokenType[] types)
{
if (!types.Contains(CurrentTokenType) || _taggedTokenValue == null || _taggedTokenValue.GetType() != typeof(string))
{
throw new InvalidOperationException($"CurrentTokenType is a {CurrentTokenType.ToString()}, not in {types}.");
}
}


private void HandleStartObject()
{
AdvanceTrue();
Expand Down

0 comments on commit 392f061

Please sign in to comment.