Skip to content

Commit

Permalink
Implement ISerialize<T> as well as ISerialize (#148)
Browse files Browse the repository at this point in the history
One more step in replacing ISerialize with ISerialize<T>.
  • Loading branch information
agocke authored Jan 12, 2024
1 parent 08ae46b commit 060025a
Show file tree
Hide file tree
Showing 80 changed files with 2,362 additions and 63 deletions.
2 changes: 1 addition & 1 deletion src/generator/Generator.Deserialize.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ partial class SerdeImplRoslynGenerator
{
private const string GeneratedVisitorName = "SerdeVisitor";

private static (MemberDeclarationSyntax[], BaseListSyntax) GenerateDeserializeImpl(
internal static (MemberDeclarationSyntax[], BaseListSyntax) GenerateDeserializeImpl(
GeneratorExecutionContext context,
ITypeSymbol receiverType,
ExpressionSyntax receiverExpr,
Expand Down
14 changes: 13 additions & 1 deletion src/generator/Generator.Impl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,18 @@ internal static void GenerateImpl(
context);
}

if (usage.HasFlag(SerdeUsage.Serialize))
{
SerializeImplRoslynGenerator.GenerateImpl(
usage,
new TypeDeclContext(typeDecl),
receiverType,
IdentifierName("value"),
context,
inProgress);

}

GenerateImpl(
usage,
new TypeDeclContext(typeDecl),
Expand Down Expand Up @@ -346,7 +358,7 @@ private static bool ImplementsSerde(ITypeSymbol memberType, GeneratorExecutionCo
private static string GetWrapperName(string typeName) => typeName + "Wrap";


private static bool HasGenerateAttribute(ITypeSymbol memberType, SerdeUsage usage)
internal static bool HasGenerateAttribute(ITypeSymbol memberType, SerdeUsage usage)
{
var attributes = memberType.GetAttributes();
foreach (var attr in attributes)
Expand Down
871 changes: 871 additions & 0 deletions src/generator/Generator.Serialize.Generic.cs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/generator/Generator.Wrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ internal static void GenerateWrapper(
var inProgress = ImmutableList.Create(receiverType);

GenerateImpl(SerdeUsage.Serialize, new TypeDeclContext(typeDecl), receiverType, receiverExpr, context, inProgress);
SerializeImplRoslynGenerator.GenerateImpl(SerdeUsage.Serialize, new TypeDeclContext(typeDecl), receiverType, receiverExpr, context, inProgress);
GenerateImpl(SerdeUsage.Deserialize, new TypeDeclContext(typeDecl), receiverType, receiverExpr, context, inProgress);
}

Expand Down
2 changes: 1 addition & 1 deletion src/generator/SymbolUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public static List<DataMemberSymbol> GetDataMembers(ITypeSymbol type, SerdeUsage
return members;
}

public static TypeSyntax ToFqnSyntax(this INamedTypeSymbol t) => SyntaxFactory.ParseTypeName(t.ToDisplayString());
public static TypeSyntax ToFqnSyntax(this ITypeSymbol t) => SyntaxFactory.ParseTypeName(t.ToDisplayString());

public static MemberOptions GetMemberOptions(ISymbol member)
{
Expand Down
1 change: 1 addition & 0 deletions src/generator/WellKnownTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace Serde
{
[Closed]
internal enum WellKnownType
{
ImmutableArray_1,
Expand Down
4 changes: 2 additions & 2 deletions src/serde-xml/XmlSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,10 @@ public void SerializeField<T>(ReadOnlySpan<byte> name, T value, ReadOnlySpan<Att
SerializeField(Encoding.UTF8.GetString(name), value, attributes);
}

void ISerializeType.SerializeField<T, U>(string name, T value, U serialize)
void ISerializeType.SerializeField<T, U>(string name, T value)
{
_parent._writer.WriteStartElement(name);
serialize.Serialize(value, _parent);
default(U).Serialize(value, _parent);
_parent._writer.WriteEndElement();
}

Expand Down
31 changes: 29 additions & 2 deletions src/serde/ISerialize.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public interface ISerialize
void Serialize(ISerializer serializer);
}

public interface ISerialize<T>
public interface ISerialize<in T>
{
void Serialize(T value, ISerializer serializer);
}
Expand All @@ -27,7 +27,9 @@ void SerializeField<T>(Utf8Span name, T value, ReadOnlySpan<Attribute> attribute
void SkipField(string name) { SkipField(Encoding.UTF8.GetBytes(name)); }
void SkipField(Utf8Span name) { }

void SerializeField<T, U>(string name, T value, U serialize) where U : ISerialize<T>;
void SerializeField<T, U>(string name, T value) where U : struct, ISerialize<T>;
void SerializeField<T, U>(string name, T value, ReadOnlySpan<Attribute> attributes) where U : struct, ISerialize<T>
=> SerializeField<T, U>(name, value);
void End();
}

Expand Down Expand Up @@ -82,6 +84,31 @@ public static void SerializeFieldIfNotNull<T, U>(
}
}

public static class ISerializeTypeExt2
{
public static void SerializeFieldIfNotNull<T, U>(
this ISerializeType serializeType,
string name,
T value) where U : struct, ISerialize<T>
=> SerializeFieldIfNotNull<T, U>(serializeType, name, value, ReadOnlySpan<Attribute>.Empty);

public static void SerializeFieldIfNotNull<T, U>(
this ISerializeType serializeType,
string name,
T value,
ReadOnlySpan<Attribute> attributes) where U : struct, ISerialize<T>
{
if (value is null)
{
serializeType.SkipField(name);
}
else
{
serializeType.SerializeField<T, U>(name, value, attributes);
}
}
}

public interface ISerializeEnumerable
{
void SerializeElement<T>(T value) where T : ISerialize;
Expand Down
39 changes: 32 additions & 7 deletions src/serde/Wrappers.Dictionary.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Net.Http.Headers;

namespace Serde
{
public static class DictWrap
{
public readonly struct SerializeImpl<TKey, TKeyWrap, TValue, TValueWrap> : ISerialize,
ISerializeWrap<Dictionary<TKey, TValue>, SerializeImpl<TKey, TKeyWrap, TValue, TValueWrap>>
public readonly struct SerializeImpl<TKey, TKeyWrap, TValue, TValueWrap>
: ISerialize, ISerialize<Dictionary<TKey, TValue>>,
ISerializeWrap<Dictionary<TKey, TValue>, SerializeImpl<TKey, TKeyWrap, TValue, TValueWrap>>
where TKey : notnull
where TKeyWrap : struct, ISerializeWrap<TKey, TKeyWrap>, ISerialize
where TValueWrap : struct, ISerializeWrap<TValue, TValueWrap>, ISerialize
where TKeyWrap : struct, ISerializeWrap<TKey, TKeyWrap>, ISerialize, ISerialize<TKey>
where TValueWrap : struct, ISerializeWrap<TValue, TValueWrap>, ISerialize, ISerialize<TValue>
{
public static SerializeImpl<TKey, TKeyWrap, TValue, TValueWrap> Create(Dictionary<TKey, TValue> t)
=> new SerializeImpl<TKey, TKeyWrap, TValue, TValueWrap>(t);
Expand All @@ -29,6 +32,17 @@ void ISerialize.Serialize(ISerializer serializer)
}
sd.End();
}

void ISerialize<Dictionary<TKey, TValue>>.Serialize(Dictionary<TKey, TValue> value, ISerializer serializer)
{
var sd = serializer.SerializeDictionary(value.Count);
foreach (var (k, v) in value)
{
sd.SerializeKey(k, TKeyWrap.Create(k));
sd.SerializeValue(v, TValueWrap.Create(v));
}
sd.End();
}
}

public readonly struct DeserializeImpl<TKey, TKeyWrap, TValue, TValueWrap> : IDeserialize<Dictionary<TKey, TValue>>
Expand Down Expand Up @@ -73,14 +87,25 @@ public Dictionary<TKey, TValue> VisitDictionary<D>(ref D d)
public static class IDictWrap
{
public readonly record struct SerializeImpl<TKey, TKeyWrap, TValue, TValueWrap>(IDictionary<TKey, TValue> Value)
: ISerialize, ISerializeWrap<IDictionary<TKey, TValue>, SerializeImpl<TKey, TKeyWrap, TValue, TValueWrap>>
: ISerialize, ISerializeWrap<IDictionary<TKey, TValue>, SerializeImpl<TKey, TKeyWrap, TValue, TValueWrap>>,
ISerialize<IDictionary<TKey, TValue>>
where TKey : notnull
where TKeyWrap : struct, ISerializeWrap<TKey, TKeyWrap>, ISerialize
where TValueWrap : struct, ISerializeWrap<TValue, TValueWrap>, ISerialize
where TKeyWrap : struct, ISerializeWrap<TKey, TKeyWrap>, ISerialize, ISerialize<TKey>
where TValueWrap : struct, ISerializeWrap<TValue, TValueWrap>, ISerialize, ISerialize<TValue>
{
public static SerializeImpl<TKey, TKeyWrap, TValue, TValueWrap> Create(IDictionary<TKey, TValue> t)
=> new SerializeImpl<TKey, TKeyWrap, TValue, TValueWrap>(t);

void ISerialize<IDictionary<TKey, TValue>>.Serialize(IDictionary<TKey, TValue> value, ISerializer serializer)
{
var sd = serializer.SerializeDictionary(value.Count);
foreach (var (k, v) in value)
{
sd.SerializeKey(k, TKeyWrap.Create(k));
sd.SerializeValue(v, TValueWrap.Create(v));
}
sd.End();
}
void ISerialize.Serialize(ISerializer serializer)
{
var sd = serializer.SerializeDictionary(Value.Count);
Expand Down
34 changes: 23 additions & 11 deletions src/serde/Wrappers.List.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ namespace Serde
{
public static class EnumerableHelpers
{
public static void SerializeSpan<T, U>(string typeName, ReadOnlySpan<T> arr, U serializeImpl, ISerializer serializer)
where U : ISerialize<T>
{
var enumerable = serializer.SerializeEnumerable(typeName, arr.Length);
foreach (var item in arr)
{
enumerable.SerializeElement(item, serializeImpl);
}
enumerable.End();
}

public static void SerializeSpan<T, TWrap>(string typeName, ReadOnlySpan<T> arr, ISerializer serializer)
where TWrap : struct, ISerializeWrap<T, TWrap>, ISerialize
{
Expand Down Expand Up @@ -46,22 +57,17 @@ public static void SerializeIList<T, TWrap>(string typeName, IList<T> list, ISer
}
}

public readonly record struct IdWrap<T>(T Value) : ISerialize, ISerializeWrap<T, IdWrap<T>>
where T : ISerialize
{
public static IdWrap<T> Create(T t) => new IdWrap<T>(t);

void ISerialize.Serialize(ISerializer serializer) => Value.Serialize(serializer);
}

public static class ArrayWrap
{
public readonly record struct SerializeImpl<T, TWrap>(T[] Value)
: ISerialize, ISerializeWrap<T[], SerializeImpl<T, TWrap>>
: ISerialize, ISerialize<T[]>, ISerializeWrap<T[], SerializeImpl<T, TWrap>>
where TWrap : struct, ISerializeWrap<T, TWrap>, ISerialize
{
public static SerializeImpl<T, TWrap> Create(T[] t) => new SerializeImpl<T, TWrap>(t);

void ISerialize<T[]>.Serialize(T[] value, ISerializer serializer)
=> EnumerableHelpers.SerializeSpan<T, TWrap>(typeof(T[]).ToString(), value, serializer);

void ISerialize.Serialize(ISerializer serializer)
=> EnumerableHelpers.SerializeSpan<T, TWrap>(typeof(T[]).ToString(), Value, serializer);
}
Expand Down Expand Up @@ -109,13 +115,16 @@ T[] IDeserializeVisitor<T[]>.VisitEnumerable<D>(ref D d)
public static class ListWrap
{
public readonly record struct SerializeImpl<T, TWrap>(List<T> Value)
: ISerialize, ISerializeWrap<List<T>, SerializeImpl<T, TWrap>>
: ISerialize, ISerialize<List<T>>, ISerializeWrap<List<T>, SerializeImpl<T, TWrap>>
where TWrap : struct, ISerializeWrap<T, TWrap>, ISerialize
{
public static SerializeImpl<T, TWrap> Create(List<T> t) => new SerializeImpl<T, TWrap>(t);

void ISerialize.Serialize(ISerializer serializer)
=> EnumerableHelpers.SerializeList<T, TWrap>(typeof(List<T>).ToString(), Value, serializer);

void ISerialize<List<T>>.Serialize(List<T> value, ISerializer serializer)
=> EnumerableHelpers.SerializeList<T, TWrap>(typeof(List<T>).ToString(), value, serializer);
}

public readonly struct DeserializeImpl<T, TWrap> : IDeserialize<List<T>>
Expand Down Expand Up @@ -158,13 +167,16 @@ List<T> IDeserializeVisitor<List<T>>.VisitEnumerable<D>(ref D d)
public static class ImmutableArrayWrap
{
public readonly record struct SerializeImpl<T, TWrap>(ImmutableArray<T> Value)
: ISerialize, ISerializeWrap<ImmutableArray<T>, SerializeImpl<T, TWrap>>
: ISerialize, ISerialize<ImmutableArray<T>>, ISerializeWrap<ImmutableArray<T>, SerializeImpl<T, TWrap>>
where TWrap : struct, ISerializeWrap<T, TWrap>, ISerialize
{
public static SerializeImpl<T, TWrap> Create(ImmutableArray<T> t) => new SerializeImpl<T, TWrap>(t);

void ISerialize.Serialize(ISerializer serializer)
=> EnumerableHelpers.SerializeSpan<T, TWrap>(typeof(ImmutableArray<T>).ToString(), Value.AsSpan(), serializer);

void ISerialize<ImmutableArray<T>>.Serialize(ImmutableArray<T> value, ISerializer serializer)
=> EnumerableHelpers.SerializeSpan<T, TWrap>(typeof(ImmutableArray<T>).ToString(), value.AsSpan(), serializer);
}

public readonly struct DeserializeImpl<T, TWrap> : IDeserialize<ImmutableArray<T>>
Expand Down
Loading

0 comments on commit 060025a

Please sign in to comment.