Skip to content

Commit

Permalink
Use generated serializers for QueryVal serialization (#145)
Browse files Browse the repository at this point in the history
  • Loading branch information
pnwpedro authored Jul 29, 2024
1 parent fa81032 commit 80ec519
Show file tree
Hide file tree
Showing 16 changed files with 233 additions and 54 deletions.
6 changes: 5 additions & 1 deletion Fauna.Test/Serialization/RoundTrip.Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ public static string Serialize(object? obj)
{
using var stream = new MemoryStream();
using var writer = new Utf8FaunaWriter(stream);
DynamicSerializer.Singleton.Serialize(ctx, writer, obj);

ISerializer ser = DynamicSerializer.Singleton;
if (obj is not null) ser = Serializer.Generate(ctx, obj.GetType());
ser.Serialize(ctx, writer, obj);

writer.Flush();
return Encoding.UTF8.GetString(stream.ToArray());
}
Expand Down
6 changes: 5 additions & 1 deletion Fauna.Test/Serialization/Serializer.Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ public static string Serialize(object? obj)
{
using var stream = new MemoryStream();
using var writer = new Utf8FaunaWriter(stream);
DynamicSerializer.Singleton.Serialize(ctx, writer, obj);

ISerializer ser = DynamicSerializer.Singleton;
if (obj is not null) ser = Serializer.Generate(ctx, obj.GetType());
ser.Serialize(ctx, writer, obj);

writer.Flush();
return Encoding.UTF8.GetString(stream.ToArray());
}
Expand Down
4 changes: 3 additions & 1 deletion Fauna/Query/QueryVal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public sealed class QueryVal : Query, IQueryFragment
/// <param name="v">The value of the specified type to be represented in the query.</param>
public QueryVal(object? v)
{

Unwrap = v;
}

Expand All @@ -31,7 +32,8 @@ public override void Serialize(MappingContext ctx, Utf8FaunaWriter writer)
{
writer.WriteStartObject();
writer.WriteFieldName("value");
DynamicSerializer.Singleton.Serialize(ctx, writer, Unwrap);
var ser = Unwrap is not null ? Serializer.Generate(ctx, Unwrap.GetType()) : DynamicSerializer.Singleton;
ser.Serialize(ctx, writer, Unwrap);
writer.WriteEndObject();
}

Expand Down
4 changes: 4 additions & 0 deletions Fauna/Serialization/ISerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ public interface ISerializer

public abstract class BaseSerializer<T> : ISerializer<T>
{
protected string UnexpectedTokenExceptionMessage(TokenType token) => $"Unexpected token `{token}` deserializing with `{GetType()}`";

protected string UnsupportedSerializationTypeMessage(Type type) => $"Cannot serialize `{type}` with `{GetType()}`";

object? ISerializer.Deserialize(MappingContext context, ref Utf8FaunaReader reader) =>
Deserialize(context, ref reader);

Expand Down
40 changes: 25 additions & 15 deletions Fauna/Serialization/Serializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
namespace Fauna.Serialization;

/// <summary>
/// Represents methods for deserializing objects to and from Fauna's value format.
/// Represents methods for serializing objects to and from Fauna's value format.
/// </summary>
public static class Serializer
{
/// <summary>
/// The dynamic data deserializer.
/// The dynamic data serializer.
/// </summary>
public static ISerializer<object?> Dynamic => DynamicSerializer.Singleton;

Expand All @@ -31,6 +31,7 @@ public static class Serializer
private static readonly DoubleSerializer _double = new();
private static readonly DateOnlySerializer _dateOnly = new();
private static readonly DateTimeSerializer _dateTime = new();
private static readonly DateTimeOffsetSerializer _dateTimeOffset = new();
private static readonly BooleanSerializer _bool = new();
private static readonly ModuleSerializer _module = new();
private static readonly DocumentSerializer<Document> _doc = new();
Expand All @@ -39,20 +40,20 @@ public static class Serializer
private static readonly DocumentSerializer<NamedRef> _namedDocRef = new();

/// <summary>
/// Generates a deserializer for the specified non-nullable .NET type.
/// Generates a serializer for the specified non-nullable .NET type.
/// </summary>
/// <typeparam name="T">The type of the object to serialize.</typeparam>
/// <param name="context">The serialization context.</param>
/// <returns>An <see cref="ISerializer{T}"/>.</returns>
public static ISerializer<T> Generate<T>(MappingContext context) where T : notnull
{
var targetType = typeof(T);
var deser = (ISerializer<T>)Generate(context, targetType);
return deser;
var ser = (ISerializer<T>)Generate(context, targetType);
return ser;
}

/// <summary>
/// Generates a deserializer for the specified non-nullable .NET type.
/// Generates a serializer for the specified non-nullable .NET type.
/// </summary>
/// <param name="context">The serialization context.</param>
/// <param name="targetType">The type of the object to serialize.</typeparam>
Expand All @@ -72,6 +73,7 @@ public static ISerializer Generate(MappingContext context, Type targetType)
if (targetType == typeof(double)) return _double;
if (targetType == typeof(DateOnly)) return _dateOnly;
if (targetType == typeof(DateTime)) return _dateTime;
if (targetType == typeof(DateTimeOffset)) return _dateTimeOffset;
if (targetType == typeof(bool)) return _bool;
if (targetType == typeof(Module)) return _module;
if (targetType == typeof(Document)) return _doc;
Expand All @@ -94,7 +96,10 @@ public static ISerializer Generate(MappingContext context, Type targetType)
throw new ArgumentException($"Unsupported nullable type. Generic arguments > 1: {args}");
}

if (targetType.IsGenericType && targetType.GetGenericTypeDefinition() == typeof(NullableDocument<>))
if (targetType.IsGenericType && (
targetType.GetGenericTypeDefinition() == typeof(NullableDocument<>) ||
targetType.GetGenericTypeDefinition() == typeof(NonNullDocument<>) ||
targetType.GetGenericTypeDefinition() == typeof(NullDocument<>)))
{
var argTypes = targetType.GetGenericArguments();
var valueType = argTypes[0];
Expand All @@ -113,36 +118,41 @@ public static ISerializer Generate(MappingContext context, Type targetType)
throw new ArgumentException(
$"Unsupported Dictionary key type. Key must be of type string, but was a {keyType}");

var valueDeserializer = Generate(context, valueType);
var valueSerializer = Generate(context, valueType);

var serType = typeof(DictionarySerializer<>).MakeGenericType(new[] { valueType });
var ser = Activator.CreateInstance(serType, new[] { valueDeserializer });
var ser = Activator.CreateInstance(serType, new[] { valueSerializer });

return (ISerializer)ser!;
}

if (targetType.IsGenericType && targetType.GetGenericTypeDefinition() == typeof(List<>))
{
var elemType = targetType.GetGenericArguments()[0];
var elemDeserializer = Generate(context, elemType);
var elemSerializer = Generate(context, elemType);

var serType = typeof(ListSerializer<>).MakeGenericType(new[] { elemType });
var ser = Activator.CreateInstance(serType, new[] { elemDeserializer });
var ser = Activator.CreateInstance(serType, new[] { elemSerializer });

return (ISerializer)ser!;
}

if (targetType.IsGenericType && targetType.GetGenericTypeDefinition() == typeof(Page<>))
{
var elemType = targetType.GetGenericArguments()[0];
var elemDeserializer = Generate(context, elemType);
var elemSerializer = Generate(context, elemType);

var serType = typeof(PageSerializer<>).MakeGenericType(new[] { elemType });
var ser = Activator.CreateInstance(serType, new[] { elemDeserializer });
var ser = Activator.CreateInstance(serType, new[] { elemSerializer });

return (ISerializer)ser!;
}

if (targetType.IsGenericType && targetType.Name.Contains("AnonymousType"))
{
return DynamicSerializer.Singleton;
}

if (targetType.IsClass && !targetType.IsGenericType)
{
var info = context.GetInfo(targetType);
Expand All @@ -153,7 +163,7 @@ public static ISerializer Generate(MappingContext context, Type targetType)
}

/// <summary>
/// Generates a deserializer which returns values of the specified .NET type, or the default if the underlying query value is null.
/// Generates a serializer which returns values of the specified .NET type, or the default if the underlying query value is null.
/// </summary>
/// <typeparam name="T">The type of the object to serialize.</typeparam>
/// <param name="context">The serialization context.</param>
Expand All @@ -166,7 +176,7 @@ public static ISerializer Generate(MappingContext context, Type targetType)
}

/// <summary>
/// Generates a deserializer which returns values of the specified .NET type, or the default if the underlying query value is null.
/// Generates a serializer which returns values of the specified .NET type, or the default if the underlying query value is null.
/// </summary>
/// <param name="context">The serialization context.</param>
/// <param name="targetType">The type of the object to serialize.</typeparam>
Expand Down
2 changes: 1 addition & 1 deletion Fauna/Serialization/Serializers/CheckedSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ public override T Deserialize(MappingContext context, ref Utf8FaunaReader reader

public override void Serialize(MappingContext context, Utf8FaunaWriter writer, object? o)
{
throw new NotImplementedException();
DynamicSerializer.Singleton.Serialize(context, writer, o);
}
}
2 changes: 1 addition & 1 deletion Fauna/Serialization/Serializers/ClassSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public override T Deserialize(MappingContext context, ref Utf8FaunaReader reader

public override void Serialize(MappingContext context, Utf8FaunaWriter writer, object? o)
{
throw new NotImplementedException();
DynamicSerializer.Singleton.Serialize(context, writer, o);
}

private object CreateInstance() => Activator.CreateInstance(_info.Type)!;
Expand Down
2 changes: 1 addition & 1 deletion Fauna/Serialization/Serializers/DictionarySerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ public override Dictionary<string, T> Deserialize(MappingContext context, ref Ut

public override void Serialize(MappingContext context, Utf8FaunaWriter writer, object? o)
{
throw new NotImplementedException();
DynamicSerializer.Singleton.Serialize(context, writer, o);
}
}
2 changes: 1 addition & 1 deletion Fauna/Serialization/Serializers/DocumentSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public override T Deserialize(MappingContext context, ref Utf8FaunaReader reader

public override void Serialize(MappingContext context, Utf8FaunaWriter writer, object? o)
{
throw new NotImplementedException();
DynamicSerializer.Singleton.Serialize(context, writer, o);
}

private T DeserializeDocument(MappingContext context, ref Utf8FaunaReader reader)
Expand Down
2 changes: 1 addition & 1 deletion Fauna/Serialization/Serializers/ListSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ public override List<T> Deserialize(MappingContext context, ref Utf8FaunaReader

public override void Serialize(MappingContext context, Utf8FaunaWriter writer, object? o)
{
throw new NotImplementedException();
DynamicSerializer.Singleton.Serialize(context, writer, o);
}
}
2 changes: 1 addition & 1 deletion Fauna/Serialization/Serializers/ModuleSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ public override Module Deserialize(MappingContext context, ref Utf8FaunaReader r

public override void Serialize(MappingContext context, Utf8FaunaWriter writer, object? o)
{
throw new NotImplementedException();
DynamicSerializer.Singleton.Serialize(context, writer, o);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ public override NullableDocument<T> Deserialize(MappingContext context, ref Utf8

public override void Serialize(MappingContext context, Utf8FaunaWriter writer, object? o)
{
throw new NotImplementedException();
DynamicSerializer.Singleton.Serialize(context, writer, o);
}
}
2 changes: 1 addition & 1 deletion Fauna/Serialization/Serializers/NullableSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ public NullableSerializer(ISerializer<T> inner)

public override void Serialize(MappingContext context, Utf8FaunaWriter writer, object? o)
{
throw new NotImplementedException();
DynamicSerializer.Singleton.Serialize(context, writer, o);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ public NullableStructSerializer(ISerializer<T> inner)

public override void Serialize(MappingContext context, Utf8FaunaWriter writer, object? o)
{
throw new NotImplementedException();
DynamicSerializer.Singleton.Serialize(context, writer, o);
}
}
2 changes: 1 addition & 1 deletion Fauna/Serialization/Serializers/PageSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,6 @@ public override Page<T> Deserialize(MappingContext context, ref Utf8FaunaReader

public override void Serialize(MappingContext context, Utf8FaunaWriter writer, object? o)
{
throw new NotImplementedException();
DynamicSerializer.Singleton.Serialize(context, writer, o);
}
}
Loading

0 comments on commit 80ec519

Please sign in to comment.