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

Use generated serializers for QueryVal serialization #145

Merged
merged 1 commit into from
Jul 29, 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
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
Loading