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

Implement ISerialize<T> as well as ISerialize #148

Merged
merged 1 commit into from
Jan 12, 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
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 @@ partial class SerdeImplRoslynGenerator
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 @@ partial class SerdeImplRoslynGenerator
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 @@ public interface ISerializeType
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 class ISerializeTypeExt
}
}

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 @@ private struct Visitor : IDeserializeVisitor<Dictionary<TKey, TValue>>
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 class EnumerableHelpers
}
}

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 @@ private struct SerdeVisitor : IDeserializeVisitor<T[]>
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
Loading