Skip to content

Commit

Permalink
Merge pull request #12 from Cysharp/explicit-order
Browse files Browse the repository at this point in the history
Add Explicit layout feature
  • Loading branch information
neuecc authored Oct 1, 2022
2 parents dd4ea81 + 34a7e87 commit 65fed91
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 26 deletions.
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ All members must be memorypack-serializable, if not, code generator reports erro

![image](https://user-images.githubusercontent.com/46207/192413557-8a47d668-5339-46c5-a3da-a77841666f81.png)

MemoryPack has 24 diagnostics rules(`MEMPACK001` to `MEMPACK024`) to be define comfortably.
MemoryPack has 24 diagnostics rules(`MEMPACK001` to `MEMPACK026`) to be define comfortably.

If target type is defined MemoryPack serialization externally and registered, use `[MemoryPackAllowSerialize]` to silent diagnostics.

Expand All @@ -141,6 +141,20 @@ public partial class Sample2

Member order is **important**, MemoryPack does not serialize any member-name and other tags, serialize in the declared order. If the type is inherited, serialize in the order of parent → child. Member orders can not change for the deserialization. For the schema evolution, see [Version tolerant](#version-tolerant) section.

Default order is sequential but you can choose explicit layout with `[MemoryPackable(SerializeLayout.Explicit)]` and `[MemoryPackOrder()]`.

```csharp
// serialize Prop0 -> Prop1
[MemoryPackable(SerializeLayout.Explicit)]
public partial class SampleExplicitOrder
{
[MemoryPackOrder(1)]
public int Prop1 { get; set; }
[MemoryPackOrder(0)]
public int Prop0 { get; set; }
}
```

### Constructor selection

MemoryPack supports parameterized constructor not only parameterless constructor. The selection of the constructor follows these rules. Both class and struct follows same.
Expand Down
10 changes: 10 additions & 0 deletions sandbox/SandboxConsoleApp/ForReadMe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,13 @@ public partial class Version2
public long Prop2 { get; set; }
public int? AddedProp { get; set; }
}


[MemoryPackable(SerializeLayout.Explicit)]
public partial class SampleExplicitOrder
{
[MemoryPackOrder(1)]
public int Prop1 { get; set; }
[MemoryPackOrder(0)]
public int Prop0 { get; set; }
}
31 changes: 30 additions & 1 deletion sandbox/SandboxConsoleApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
using System.Text;
using System.Xml.Linq;

var a = int.MaxValue;
var b = ~a;
Console.WriteLine(b);

Console.WriteLine("foo");

// ---

Expand All @@ -43,6 +45,33 @@



[MemoryPackable(GenerateType.Object)]
public partial class Sonota1
{
// public NoSerializableObject? MyProperty { get; set; }
}

public class NoSerializableObject
{

}

[MemoryPackable(SerializeLayout.Explicit)]
public partial class Sonota2
{
[MemoryPackOrder(1)]
public int MyProperty1 { get; set; }
[MemoryPackOrder(0)]
public int MyProperty2 { get; set; }
}

[MemoryPackable(GenerateType.Object, SerializeLayout.Explicit)]
public partial class Sonota3
{
[MemoryPackOrder(0)]
public int MyProperty { get; set; }
}




Expand Down
45 changes: 35 additions & 10 deletions src/MemoryPack.Core/Attributes.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
namespace MemoryPack;
using System.Runtime.InteropServices;

namespace MemoryPack;

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false, Inherited = false)]
public sealed class MemoryPackableAttribute : Attribute
{
public GenerateType GenerateType { get; }
public SerializeLayout SerializeLayout { get; }

// ctor parameter count is used in MemoryPackGenerator.Parser TypeMeta for detect which ctor used.
// if modify ctor, be careful.

public MemoryPackableAttribute(GenerateType generateType = GenerateType.Object)
public MemoryPackableAttribute(GenerateType generateType = GenerateType.Object, SerializeLayout serializeLayout = SerializeLayout.Sequential)
{
this.GenerateType = generateType;
this.SerializeLayout = serializeLayout;
}

// set SerializeLayout only allows Object
public MemoryPackableAttribute(SerializeLayout serializeLayout)
{
this.GenerateType = GenerateType.Object;
this.SerializeLayout = serializeLayout;
}
}

Expand All @@ -18,11 +32,17 @@ public enum GenerateType
NoGenerate
}

public enum SerializeLayout
{
Sequential, // default
Explicit
}

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)]
public sealed class MemoryPackUnionAttribute : Attribute
{
public byte Tag { get; set; }
public Type Type { get; set; }
public byte Tag { get; }
public Type Type { get; }

public MemoryPackUnionAttribute(byte tag, Type type)
{
Expand All @@ -31,17 +51,22 @@ public MemoryPackUnionAttribute(byte tag, Type type)
}
}

// initial design, does not provide this.
//[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
//public sealed class MemoryPackGenerateAttribute : Attribute
//{
//}

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public sealed class MemoryPackAllowSerializeAttribute : Attribute
{
}

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public sealed class MemoryPackOrderAttribute : Attribute
{
public int Order { get; }

public MemoryPackOrderAttribute(int order)
{
this.Order = order;
}
}

// similar naming as System.Text.Json attribtues
// https://docs.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonattribute

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@ public enum GenerateType
Collection,
NoGenerate
}

public enum SerializeLayout
{
Sequential, // default
Explicit
}
16 changes: 16 additions & 0 deletions src/MemoryPack.Generator/DiagnosticDescriptors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,4 +204,20 @@ internal static class DiagnosticDescriptors
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);

public static readonly DiagnosticDescriptor AllMembersMustAnnotateOrder = new(
id: "MEMPACK025",
title: "All members must annotate MemoryPackOrder when SerializeLayout.Explicit",
messageFormat: "The MemoryPackable object '{0}' member '{1}' is not annotated MemoryPackOrder",
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);

public static readonly DiagnosticDescriptor AllMembersMustBeContinuousNumber = new(
id: "MEMPACK026",
title: "All MemoryPackOrder members must be continuous number from zero",
messageFormat: "The MemoryPackable object '{0}' member '{1}' is not continuous number from zero",
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);
}
Loading

0 comments on commit 65fed91

Please sign in to comment.