Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8dc82c5
remove
sator-imaging Aug 13, 2026
11a7e7c
fix
sator-imaging Aug 13, 2026
f795bc7
fix
sator-imaging Aug 13, 2026
084022f
fix 3
sator-imaging Aug 13, 2026
3ab4132
fix 4
sator-imaging Aug 13, 2026
0db64bf
fix 5
sator-imaging Aug 14, 2026
71078ef
Fix tests for nullable nested-struct view behavior (#78)
sator-imaging Aug 14, 2026
a927661
Apply suggestion from @sator-imaging
sator-imaging Aug 14, 2026
c96e2c9
Apply suggestion from @sator-imaging
sator-imaging Aug 14, 2026
51ec2c6
Apply suggestion from @sator-imaging
sator-imaging Aug 14, 2026
3447488
Apply suggestion from @sator-imaging
sator-imaging Aug 14, 2026
441ce14
Apply suggestion from @sator-imaging
sator-imaging Aug 15, 2026
0d63406
fix error
sator-imaging Aug 20, 2026
f78186f
fix error 2
sator-imaging Aug 20, 2026
58bd276
fix error 3
sator-imaging Aug 20, 2026
342ff30
fix error 4
sator-imaging Aug 20, 2026
65e9ae6
fix error 5
sator-imaging Aug 20, 2026
d40c388
Apply suggestions from code review
sator-imaging Aug 21, 2026
1e110a0
Apply suggestions from code review
sator-imaging Aug 21, 2026
08359f5
fix error
sator-imaging Aug 21, 2026
5a57983
Apply suggestion from @sator-imaging
sator-imaging Aug 21, 2026
e50ab5b
Merge branch 'main' into new2/remove-unauthorized-spec
sator-imaging Aug 28, 2026
39846dc
fix test
sator-imaging Aug 28, 2026
90e6a17
add missing verification
sator-imaging Aug 28, 2026
8015059
Apply suggestion from @sator-imaging
sator-imaging Aug 28, 2026
ab3dc93
Apply suggestion from @sator-imaging
sator-imaging Aug 28, 2026
eb8b41e
Apply batched suggestions from code review
sator-imaging Aug 28, 2026
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
8 changes: 4 additions & 4 deletions benchmark/Benchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,10 @@ public int DeserializeAllProperties()
ReadOnlySpan<int> integers = view.Integers;
ReadOnlySpan<long> longs = view.Longs;
ReadOnlySpan<PackedBenchmarkValue> packedValues = view.PackedValues;
NestedPayloadView nested = view.Nested;
int nestedVersion = nested.Version;
ReadOnlySpan<char> nestedLabel = nested.Label;
PackedBenchmarkValueView nestedSummary = nested.Summary;
NestedPayloadView? nested = view.Nested;
int nestedVersion = nested?.Version ?? -1;
ReadOnlySpan<char> nestedLabel = (nested ?? new()).Label; // Nullable<ReadOnlySpan<char>> is invalid
PackedBenchmarkValueView nestedSummary = nested?.Summary ?? new();
Comment thread
sator-imaging marked this conversation as resolved.
Outdated
NestedStructPayloadView nestedStruct = view.NestedStruct;
int nestedStructCode = nestedStruct.Code;
long nestedStructAmount = nestedStruct.Amount;
Expand Down
2 changes: 2 additions & 0 deletions src/FieldGenerationModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ internal FieldGenerationModel(

internal int ElementByteCount { get; }

internal int BlittableByteOffset { get; set; }

internal ITypeSymbol? ArrayElementType { get; }

internal INamedTypeSymbol? NestedSerializableType { get; }
Expand Down
33 changes: 22 additions & 11 deletions src/ZeroSerializerGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@
}

// Roslyn's member order is the wire declaration order; never infer a different order from file paths or spans.
int blittableByteOffset = 0;
foreach (ISymbol declaredMember in serializableType.GetMembers())
{
// Only public getter properties define the wire contract; fields, setters, and indexers must never leak into it.
Expand Down Expand Up @@ -398,7 +399,9 @@
serializableProperty.Name));
}

propertyModel.BlittableByteOffset = blittableByteOffset;
generationModel.Fields.Add(propertyModel);
blittableByteOffset += propertyModel.ElementByteCount;
}

return generationModel;
Expand Down Expand Up @@ -1272,14 +1275,28 @@
propertyType = field.Symbol.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
}

sourceBuilder.AppendLine($"{propertyAccessibility} {propertyType} {EscapeIdentifier(field.Symbol.Name)}");
var propertyReturnType
= field.Kind is FieldSerializationKind.BlittableStruct or FieldSerializationKind.Nested
? (field.NullableUnderlyingType is not null || field.Symbol.Type.TypeKind is TypeKind.Class)
? GetQualifiedViewName(field.NestedSerializableType) + "?"

Check warning on line 1281 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Debug)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.

Check warning on line 1281 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Debug)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.

Check warning on line 1281 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Release)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.

Check warning on line 1281 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Release)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.

Check warning on line 1281 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / test (Debug)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.

Check warning on line 1281 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / test (Release)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.

Check warning on line 1281 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / benchmark (net5.0, .NET 5)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.

Check warning on line 1281 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / benchmark (net5.0, .NET 5)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.

Check warning on line 1281 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / benchmark (net10.0, .NET 10)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.

Check warning on line 1281 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / benchmark (net10.0, .NET 10)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.
: GetQualifiedViewName(field.NestedSerializableType)

Check warning on line 1282 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Debug)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.

Check warning on line 1282 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Debug)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.

Check warning on line 1282 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Release)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.

Check warning on line 1282 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Release)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.

Check warning on line 1282 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / test (Debug)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.

Check warning on line 1282 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / test (Release)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.

Check warning on line 1282 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / benchmark (net5.0, .NET 5)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.

Check warning on line 1282 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / benchmark (net5.0, .NET 5)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.

Check warning on line 1282 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / benchmark (net10.0, .NET 10)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.

Check warning on line 1282 in src/ZeroSerializerGenerator.cs

View workflow job for this annotation

GitHub Actions / benchmark (net10.0, .NET 10)

Possible null reference argument for parameter 'symbol' in 'string ZeroSerializerGenerator.GetQualifiedViewName(INamedTypeSymbol symbol)'.
Comment thread
sator-imaging marked this conversation as resolved.
: propertyType;
sourceBuilder.AppendLine($"{propertyAccessibility} {propertyReturnType} {EscapeIdentifier(field.Symbol.Name)}");
sourceBuilder.OpenBlock();
sourceBuilder.AppendLine("get");
sourceBuilder.OpenBlock();
if (containingModel.IsBlittableStruct)
{
sourceBuilder.AppendLine($"{containingModel.QualifiedSourceTypeName} blittableSourceValue = MemoryMarshal.Read<{containingModel.QualifiedSourceTypeName}>(serializedMemory.Span);");
sourceBuilder.AppendLine($"return blittableSourceValue.{EscapeIdentifier(field.Symbol.Name)};");
if (field.Kind == FieldSerializationKind.BlittableStruct
&& field.NestedSerializableType is not null)
{
sourceBuilder.AppendLine($"return new {GetQualifiedViewName(field.NestedSerializableType)}(serializedMemory.Slice({field.BlittableByteOffset}, {field.ElementByteCount}));");
}
else
{
sourceBuilder.AppendLine($"{containingModel.QualifiedSourceTypeName} blittableSourceValue = MemoryMarshal.Read<{containingModel.QualifiedSourceTypeName}>(serializedMemory.Span);");
sourceBuilder.AppendLine($"return blittableSourceValue.{EscapeIdentifier(field.Symbol.Name)};");
}
sourceBuilder.CloseBlock();
sourceBuilder.CloseBlock();
return;
Expand All @@ -1292,14 +1309,8 @@
// Null is represented entirely by the offset table; no property payload marker is read.
sourceBuilder.AppendLine("if (fieldDataOffset == 0)");
sourceBuilder.OpenBlock();
if (field.NullableUnderlyingType is not null && field.Kind != FieldSerializationKind.Nested)
{
sourceBuilder.AppendLine("return null;");
}
else
{
sourceBuilder.AppendLine("return default;");
}
// Always use 'default' instead of 'null' for reference types.
sourceBuilder.AppendLine("return default;");
sourceBuilder.CloseBlock();
}

Expand Down
6 changes: 3 additions & 3 deletions tests-unity/UnityCompatibility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,11 @@
&& variableView.OptionalState == PacketState.Ready
&& variableView.OptionalPosition!.Value.X == 30
&& variableView.MissingOptionalPosition is null
&& variableView.Child.Identifier == 99
&& variableView.Child?.Identifier == 99
&& variableView.StructChild.Identifier == 100
&& variableView.StructChild.Name.SequenceEqual("struct".AsSpan())
&& variableView.OptionalStructChild.Identifier == 101
&& variableView.OptionalStructChild.Name.SequenceEqual("optional struct".AsSpan())
&& variableView.OptionalStructChild?.Identifier == 101
&& variableView.OptionalStructChild?.Name.SequenceEqual("optional struct".AsSpan()) == true
&& variableView.FloatValues.Length == 3
&& variableView.FloatValues[1] == 2.5f
&& variableView.DoubleValues.Length == 3
Expand Down Expand Up @@ -267,7 +267,7 @@
}

[ZeroSerializer]
public struct FixedPacket

Check warning on line 270 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Debug)

Struct 'FixedPacket' has a Blittable-compatible field shape; use StructLayout(LayoutKind.Sequential, Pack = 1) to enable raw payload serialization

Check warning on line 270 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Debug)

Struct 'FixedPacket' has a Blittable-compatible field shape; use StructLayout(LayoutKind.Sequential, Pack = 1) to enable raw payload serialization

Check warning on line 270 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Release)

Struct 'FixedPacket' has a Blittable-compatible field shape; use StructLayout(LayoutKind.Sequential, Pack = 1) to enable raw payload serialization

Check warning on line 270 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Release)

Struct 'FixedPacket' has a Blittable-compatible field shape; use StructLayout(LayoutKind.Sequential, Pack = 1) to enable raw payload serialization

Check warning on line 270 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / test (Debug)

Struct 'FixedPacket' has a Blittable-compatible field shape; use StructLayout(LayoutKind.Sequential, Pack = 1) to enable raw payload serialization

Check warning on line 270 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / test (Release)

Struct 'FixedPacket' has a Blittable-compatible field shape; use StructLayout(LayoutKind.Sequential, Pack = 1) to enable raw payload serialization
{
public bool BooleanValue { get; init; }

Expand Down Expand Up @@ -400,13 +400,13 @@
public int IgnoredField;
}

[ZeroSerializer(EmitShapeTag = true)]

Check warning on line 403 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Debug)

'ZeroSerializerAttribute.EmitShapeTag' is obsolete: 'Emitting string representation of the type will expose internal details in the resulting assembly. Consider using `ShapeHash` instead, or using `#if DEBUG` directive to prevent emitting on release build.'

Check warning on line 403 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Release)

'ZeroSerializerAttribute.EmitShapeTag' is obsolete: 'Emitting string representation of the type will expose internal details in the resulting assembly. Consider using `ShapeHash` instead, or using `#if DEBUG` directive to prevent emitting on release build.'

Check warning on line 403 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / test (Debug)

'ZeroSerializerAttribute.EmitShapeTag' is obsolete: 'Emitting string representation of the type will expose internal details in the resulting assembly. Consider using `ShapeHash` instead, or using `#if DEBUG` directive to prevent emitting on release build.'

Check warning on line 403 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / test (Release)

'ZeroSerializerAttribute.EmitShapeTag' is obsolete: 'Emitting string representation of the type will expose internal details in the resulting assembly. Consider using `ShapeHash` instead, or using `#if DEBUG` directive to prevent emitting on release build.'
public sealed class EmptyClassPacket
{
}

[ZeroSerializer(EmitShapeTag = true)]

Check warning on line 408 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Debug)

'ZeroSerializerAttribute.EmitShapeTag' is obsolete: 'Emitting string representation of the type will expose internal details in the resulting assembly. Consider using `ShapeHash` instead, or using `#if DEBUG` directive to prevent emitting on release build.'

Check warning on line 408 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Release)

'ZeroSerializerAttribute.EmitShapeTag' is obsolete: 'Emitting string representation of the type will expose internal details in the resulting assembly. Consider using `ShapeHash` instead, or using `#if DEBUG` directive to prevent emitting on release build.'

Check warning on line 408 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / test (Debug)

'ZeroSerializerAttribute.EmitShapeTag' is obsolete: 'Emitting string representation of the type will expose internal details in the resulting assembly. Consider using `ShapeHash` instead, or using `#if DEBUG` directive to prevent emitting on release build.'

Check warning on line 408 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / test (Release)

'ZeroSerializerAttribute.EmitShapeTag' is obsolete: 'Emitting string representation of the type will expose internal details in the resulting assembly. Consider using `ShapeHash` instead, or using `#if DEBUG` directive to prevent emitting on release build.'
public struct EmptyStructPacket

Check warning on line 409 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Debug)

Struct 'EmptyStructPacket' has a Blittable-compatible field shape; use StructLayout(LayoutKind.Sequential, Pack = 1) to enable raw payload serialization

Check warning on line 409 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Release)

Struct 'EmptyStructPacket' has a Blittable-compatible field shape; use StructLayout(LayoutKind.Sequential, Pack = 1) to enable raw payload serialization

Check warning on line 409 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / test (Debug)

Struct 'EmptyStructPacket' has a Blittable-compatible field shape; use StructLayout(LayoutKind.Sequential, Pack = 1) to enable raw payload serialization

Check warning on line 409 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / test (Release)

Struct 'EmptyStructPacket' has a Blittable-compatible field shape; use StructLayout(LayoutKind.Sequential, Pack = 1) to enable raw payload serialization
{
}

Expand Down Expand Up @@ -443,7 +443,7 @@
}

[ZeroSerializer]
public record struct UnitySimpleRecordStruct

Check warning on line 446 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Debug)

Struct 'UnitySimpleRecordStruct' has a Blittable-compatible field shape; use StructLayout(LayoutKind.Sequential, Pack = 1) to enable raw payload serialization

Check warning on line 446 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / generated-source-preview / preview (Release)

Struct 'UnitySimpleRecordStruct' has a Blittable-compatible field shape; use StructLayout(LayoutKind.Sequential, Pack = 1) to enable raw payload serialization

Check warning on line 446 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / test (Debug)

Struct 'UnitySimpleRecordStruct' has a Blittable-compatible field shape; use StructLayout(LayoutKind.Sequential, Pack = 1) to enable raw payload serialization

Check warning on line 446 in tests-unity/UnityCompatibility.cs

View workflow job for this annotation

GitHub Actions / test (Release)

Struct 'UnitySimpleRecordStruct' has a Blittable-compatible field shape; use StructLayout(LayoutKind.Sequential, Pack = 1) to enable raw payload serialization
{
public int IntValue { get; init; }
public double DoubleValue { get; init; }
Expand Down
44 changes: 23 additions & 21 deletions tests/SerializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,12 @@ public void VariableDataRoundTrip()

int expectedRequiredByteLength = -(24 + (4 * IntPtr.Size));
TestAssert.Equal(expectedRequiredByteLength, VariableRecordView.RequiredByteLength, nameof(VariableRecordView.RequiredByteLength));
TestAssert.Equal(source.Text, view.Text.ToString(), nameof(view.Text));
TestAssert.SequenceEqual<int>(source.Values, view.Values, nameof(view.Values));
TestAssert.Equal(source.OptionalNumber, view.OptionalNumber, nameof(view.OptionalNumber));
TestAssert.Equal(source.Child.Identifier, view.Child.Identifier, nameof(view.Child.Identifier));
TestAssert.Equal(source.Child.State, view.Child.State, nameof(view.Child.State));
TestAssert.Equal(source.Tail, view.Tail, nameof(view.Tail));
TestAssert.Equal(source.Text, view.Text.ToString(), nameof(source.Text));
TestAssert.SequenceEqual<int>(source.Values, view.Values, nameof(source.Values));
TestAssert.Equal(source.OptionalNumber, view.OptionalNumber, nameof(source.OptionalNumber));
TestAssert.Equal(source.Child.Identifier, view.Child?.Identifier ?? -1, nameof(source.Child.Identifier));
TestAssert.Equal(source.Child.State, view.Child?.State ?? ByteState.None, nameof(source.Child.State));
Comment thread
sator-imaging marked this conversation as resolved.
Outdated
TestAssert.Equal(source.Tail, view.Tail, nameof(source.Tail));
Comment thread
sator-imaging marked this conversation as resolved.
int textFieldOffset = BinaryPrimitives.ReadInt32LittleEndian(buffer.AsSpan(0, 4));
int valuesFieldOffset = BinaryPrimitives.ReadInt32LittleEndian(buffer.AsSpan(4, 4));
int optionalNumberFieldOffset = BinaryPrimitives.ReadInt32LittleEndian(buffer.AsSpan(8, 4));
Expand Down Expand Up @@ -284,8 +284,8 @@ public void VariableViewOnlyRequiresCorrectSerializedStart()
TestAssert.Equal(source.Text, view.Text.ToString(), nameof(view.Text));
TestAssert.SequenceEqual<int>(source.Values, view.Values, nameof(view.Values));
TestAssert.Equal(source.OptionalNumber, view.OptionalNumber, nameof(view.OptionalNumber));
TestAssert.Equal(source.Child.Identifier, view.Child.Identifier, nameof(view.Child.Identifier));
TestAssert.Equal(source.Child.State, view.Child.State, nameof(view.Child.State));
TestAssert.Equal(source.Child.Identifier, view.Child?.Identifier ?? -1, nameof(FixedClassView.Identifier));
TestAssert.Equal(source.Child.State, view.Child?.State ?? ByteState.None, nameof(FixedClassView.State));
Comment thread
sator-imaging marked this conversation as resolved.
Outdated
TestAssert.Equal(source.Tail, view.Tail, nameof(view.Tail));

ReadOnlyMemory<byte> borrowedSerializedMemory = view;
Expand All @@ -309,15 +309,17 @@ public void NullValuesRoundTrip()
int writtenBytes = source.Serialize(buffer);
var view = new VariableRecordView(buffer.AsMemory(0, writtenBytes));

TestAssert.Equal(0, view.Text.Length, nameof(view.Text.Length));
TestAssert.Equal(0, view.Values.Length, nameof(view.Values.Length));
TestAssert.Equal<int?>(null, view.OptionalNumber, nameof(view.OptionalNumber));
TestAssert.Equal(0, BinaryPrimitives.ReadInt32LittleEndian(buffer.AsSpan(0, 4)), "Null string offset");
TestAssert.Equal(0, BinaryPrimitives.ReadInt32LittleEndian(buffer.AsSpan(4, 4)), "Null array offset");
TestAssert.Equal(0, BinaryPrimitives.ReadInt32LittleEndian(buffer.AsSpan(8, 4)), "Null nullable offset");
TestAssert.Equal(0, BinaryPrimitives.ReadInt32LittleEndian(buffer.AsSpan(12, 4)), "Null reference offset");
TestAssert.Equal(20, BinaryPrimitives.ReadInt32LittleEndian(buffer.AsSpan(16, 4)), "Tail offset");
TestAssert.Equal(24, writtenBytes, nameof(writtenBytes));

TestAssert.Equal(0, view.Text.Length, nameof(view.Text.Length));
TestAssert.Equal(0, view.Values.Length, nameof(view.Values.Length));
TestAssert.Equal<int?>(null, view.OptionalNumber, nameof(view.OptionalNumber));
TestAssert.Equal<FixedClassView?>(null, view.Child, nameof(view.Child));
TestAssert.Equal(5, view.Tail, nameof(view.Tail));
}

Expand Down Expand Up @@ -521,9 +523,9 @@ public void EveryTruncatedSerializedBufferThrowsStandardBoundsExceptionWhenRead(
_ = view.Text.Length;
_ = view.Values.Length;
_ = view.OptionalNumber;
FixedClassView childView = view.Child;
_ = childView.Identifier;
_ = childView.State;
FixedClassView? childView = view.Child;
_ = childView?.Identifier;
_ = childView?.State;
_ = view.Tail;
},
nameof(VariableRecord));
Expand Down Expand Up @@ -777,7 +779,7 @@ public void NestedTypesReturnViewsTest()
// 2. Assert that nested non-blittable type returns view
PropertyInfo? childProperty = typeof(VariableRecordView).GetProperty(nameof(VariableRecordView.Child));
Assert.NotNull(childProperty);
Assert.Equal(typeof(FixedClassView), childProperty!.PropertyType);
Assert.Equal(typeof(FixedClassView?), childProperty!.PropertyType);
}

public void StrictBlittableStructTests()
Expand Down Expand Up @@ -1301,13 +1303,13 @@ public void SharedReferenceInstancesRoundTrip()
int writtenBytes = container.Serialize(buffer);
var view = new DuplicateInstanceContainerView(buffer.AsMemory(0, writtenBytes));

TestAssert.Equal(100, view.Foo.Value, nameof(view.Foo.Value));
TestAssert.Equal(100, view.Bar.Value, nameof(view.Bar.Value));
TestAssert.Equal(200, view.Baz.Value, nameof(view.Baz.Value));
TestAssert.Equal(100, view.Foo?.Value, nameof(container.Foo.Value));
TestAssert.Equal(100, view.Bar?.Value, nameof(container.Bar.Value));
TestAssert.Equal(200, view.Baz?.Value, nameof(container.Baz.Value));

TestAssert.Equal(42, view.Foo.Nested.NestedValue, nameof(view.Foo.Nested.NestedValue));
TestAssert.Equal(42, view.Bar.Nested.NestedValue, nameof(view.Bar.Nested.NestedValue));
TestAssert.Equal(42, view.Baz.Nested.NestedValue, nameof(view.Baz.Nested.NestedValue));
TestAssert.Equal(42, view.Foo?.Nested?.NestedValue, nameof(container.Foo.Nested.NestedValue));
TestAssert.Equal(42, view.Bar?.Nested?.NestedValue, nameof(container.Bar.Nested.NestedValue));
TestAssert.Equal(42, view.Baz?.Nested?.NestedValue, nameof(container.Baz.Nested.NestedValue));

TestAssert.Equal(writtenBytes, view.GetByteLength(), "SharedReferenceInstances GetByteLength");
}
Expand Down
Loading