Skip to content

Commit 65fed91

Browse files
authored
Merge pull request #12 from Cysharp/explicit-order
Add Explicit layout feature
2 parents dd4ea81 + 34a7e87 commit 65fed91

File tree

9 files changed

+239
-26
lines changed

9 files changed

+239
-26
lines changed

README.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ All members must be memorypack-serializable, if not, code generator reports erro
126126

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

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

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

@@ -141,6 +141,20 @@ public partial class Sample2
141141

142142
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.
143143

144+
Default order is sequential but you can choose explicit layout with `[MemoryPackable(SerializeLayout.Explicit)]` and `[MemoryPackOrder()]`.
145+
146+
```csharp
147+
// serialize Prop0 -> Prop1
148+
[MemoryPackable(SerializeLayout.Explicit)]
149+
public partial class SampleExplicitOrder
150+
{
151+
[MemoryPackOrder(1)]
152+
public int Prop1 { get; set; }
153+
[MemoryPackOrder(0)]
154+
public int Prop0 { get; set; }
155+
}
156+
```
157+
144158
### Constructor selection
145159

146160
MemoryPack supports parameterized constructor not only parameterless constructor. The selection of the constructor follows these rules. Both class and struct follows same.

sandbox/SandboxConsoleApp/ForReadMe.cs

+10
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,13 @@ public partial class Version2
138138
public long Prop2 { get; set; }
139139
public int? AddedProp { get; set; }
140140
}
141+
142+
143+
[MemoryPackable(SerializeLayout.Explicit)]
144+
public partial class SampleExplicitOrder
145+
{
146+
[MemoryPackOrder(1)]
147+
public int Prop1 { get; set; }
148+
[MemoryPackOrder(0)]
149+
public int Prop0 { get; set; }
150+
}

sandbox/SandboxConsoleApp/Program.cs

+30-1
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
using System.Text;
2121
using System.Xml.Linq;
2222

23+
var a = int.MaxValue;
24+
var b = ~a;
25+
Console.WriteLine(b);
2326

24-
Console.WriteLine("foo");
2527

2628
// ---
2729

@@ -43,6 +45,33 @@
4345

4446

4547

48+
[MemoryPackable(GenerateType.Object)]
49+
public partial class Sonota1
50+
{
51+
// public NoSerializableObject? MyProperty { get; set; }
52+
}
53+
54+
public class NoSerializableObject
55+
{
56+
57+
}
58+
59+
[MemoryPackable(SerializeLayout.Explicit)]
60+
public partial class Sonota2
61+
{
62+
[MemoryPackOrder(1)]
63+
public int MyProperty1 { get; set; }
64+
[MemoryPackOrder(0)]
65+
public int MyProperty2 { get; set; }
66+
}
67+
68+
[MemoryPackable(GenerateType.Object, SerializeLayout.Explicit)]
69+
public partial class Sonota3
70+
{
71+
[MemoryPackOrder(0)]
72+
public int MyProperty { get; set; }
73+
}
74+
4675

4776

4877

src/MemoryPack.Core/Attributes.cs

+35-10
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
1-
namespace MemoryPack;
1+
using System.Runtime.InteropServices;
2+
3+
namespace MemoryPack;
24

35
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false, Inherited = false)]
46
public sealed class MemoryPackableAttribute : Attribute
57
{
68
public GenerateType GenerateType { get; }
9+
public SerializeLayout SerializeLayout { get; }
10+
11+
// ctor parameter count is used in MemoryPackGenerator.Parser TypeMeta for detect which ctor used.
12+
// if modify ctor, be careful.
713

8-
public MemoryPackableAttribute(GenerateType generateType = GenerateType.Object)
14+
public MemoryPackableAttribute(GenerateType generateType = GenerateType.Object, SerializeLayout serializeLayout = SerializeLayout.Sequential)
915
{
1016
this.GenerateType = generateType;
17+
this.SerializeLayout = serializeLayout;
18+
}
19+
20+
// set SerializeLayout only allows Object
21+
public MemoryPackableAttribute(SerializeLayout serializeLayout)
22+
{
23+
this.GenerateType = GenerateType.Object;
24+
this.SerializeLayout = serializeLayout;
1125
}
1226
}
1327

@@ -18,11 +32,17 @@ public enum GenerateType
1832
NoGenerate
1933
}
2034

35+
public enum SerializeLayout
36+
{
37+
Sequential, // default
38+
Explicit
39+
}
40+
2141
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)]
2242
public sealed class MemoryPackUnionAttribute : Attribute
2343
{
24-
public byte Tag { get; set; }
25-
public Type Type { get; set; }
44+
public byte Tag { get; }
45+
public Type Type { get; }
2646

2747
public MemoryPackUnionAttribute(byte tag, Type type)
2848
{
@@ -31,17 +51,22 @@ public MemoryPackUnionAttribute(byte tag, Type type)
3151
}
3252
}
3353

34-
// initial design, does not provide this.
35-
//[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
36-
//public sealed class MemoryPackGenerateAttribute : Attribute
37-
//{
38-
//}
39-
4054
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
4155
public sealed class MemoryPackAllowSerializeAttribute : Attribute
4256
{
4357
}
4458

59+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
60+
public sealed class MemoryPackOrderAttribute : Attribute
61+
{
62+
public int Order { get; }
63+
64+
public MemoryPackOrderAttribute(int order)
65+
{
66+
this.Order = order;
67+
}
68+
}
69+
4570
// similar naming as System.Text.Json attribtues
4671
// https://docs.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonattribute
4772

src/MemoryPack.Generator/GenerateType.cs renamed to src/MemoryPack.Generator/CoreEnums.cs

+6
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,9 @@ public enum GenerateType
77
Collection,
88
NoGenerate
99
}
10+
11+
public enum SerializeLayout
12+
{
13+
Sequential, // default
14+
Explicit
15+
}

src/MemoryPack.Generator/DiagnosticDescriptors.cs

+16
Original file line numberDiff line numberDiff line change
@@ -204,4 +204,20 @@ internal static class DiagnosticDescriptors
204204
category: Category,
205205
defaultSeverity: DiagnosticSeverity.Error,
206206
isEnabledByDefault: true);
207+
208+
public static readonly DiagnosticDescriptor AllMembersMustAnnotateOrder = new(
209+
id: "MEMPACK025",
210+
title: "All members must annotate MemoryPackOrder when SerializeLayout.Explicit",
211+
messageFormat: "The MemoryPackable object '{0}' member '{1}' is not annotated MemoryPackOrder",
212+
category: Category,
213+
defaultSeverity: DiagnosticSeverity.Error,
214+
isEnabledByDefault: true);
215+
216+
public static readonly DiagnosticDescriptor AllMembersMustBeContinuousNumber = new(
217+
id: "MEMPACK026",
218+
title: "All MemoryPackOrder members must be continuous number from zero",
219+
messageFormat: "The MemoryPackable object '{0}' member '{1}' is not continuous number from zero",
220+
category: Category,
221+
defaultSeverity: DiagnosticSeverity.Error,
222+
isEnabledByDefault: true);
207223
}

0 commit comments

Comments
 (0)