Skip to content

Commit

Permalink
Add implicit operator to Union types (#438)
Browse files Browse the repository at this point in the history
  • Loading branch information
trumully authored May 31, 2024
1 parent ddbe4be commit cc0659d
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 1 deletion.
12 changes: 11 additions & 1 deletion src/FlatSharp.Compiler/SchemaModel/ReferenceUnionSchemaModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ protected override void OnWriteCode(CodeWriter writer, CompileContext context)
{
this.WriteConstructor(writer, item.resolvedType, item.value, item.propertyType);
this.AddUnionMember(writer, item.resolvedType, item.value, item.propertyType, context);
this.WriteImplicitOperator(writer, item.resolvedType);
}

this.WriteDefaultConstructor(writer);
Expand Down Expand Up @@ -251,7 +252,16 @@ private void WriteConstructor(CodeWriter writer, string resolvedType, EnumVal un
}
}

private void WriteDefaultConstructor(CodeWriter writer)
private void WriteImplicitOperator(CodeWriter writer, string resolvedType)
{
writer.AppendLine($"public static implicit operator {this.Name}({resolvedType} value)");
using (writer.WithBlock())
{
writer.AppendLine($"return new {this.Name}(value);");
}
}

private void WriteDefaultConstructor(CodeWriter writer)
{
writer.AppendLine($"protected {this.Name}()");
using (writer.WithBlock())
Expand Down
10 changes: 10 additions & 0 deletions src/FlatSharp.Compiler/SchemaModel/ValueUnionSchemaModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ protected override void OnWriteCode(CodeWriter writer, CompileContext context)
}

this.WriteConstructor(writer, item.resolvedType, item.value, propertyClrType, generateUnsafeItems);
this.WriteImplicitOperator(writer, item.resolvedType);
this.WriteUncheckedGetItemMethod(writer, item.resolvedType, item.value, propertyClrType, generateUnsafeItems);

writer.AppendLine();
Expand Down Expand Up @@ -363,4 +364,13 @@ private void WriteConstructor(CodeWriter writer, string resolvedType, EnumVal un
}
}
}

private void WriteImplicitOperator(CodeWriter writer, string resolvedType)
{
writer.AppendLine($"public static implicit operator {this.Name}({resolvedType} value)");
using (writer.WithBlock())
{
writer.AppendLine($"return new {this.Name}(value);");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
namespace FlatSharpEndToEndTests.UnionImplicitOperator;

[TestClass]
public class UnionImplicitOperatorTests
{
[TestMethod]
public void ImplicitOperator_Struct()
{
A a = new A { V = 1 };

StructUnion u = a;

Assert.AreEqual(u.GetType(), typeof(StructUnion));
Assert.AreEqual(a.V, u.A.V);
}

[TestMethod]
public void ImplicitOperator_ValueStruct()
{
Vec3 v = new Vec3 { X = 1, Y = 2, Z = 3 };

StructUnion u = v;

Assert.AreEqual(u.GetType(), typeof(StructUnion));
Assert.AreEqual(v.X, u.Vec3.X);
}

[TestMethod]
public void ImplicitOperator_Table()
{
MyTable t = new MyTable { Field = "hello", Value = 42 };

TableUnion u = t;

Assert.AreEqual(u.GetType(), typeof(TableUnion));
Assert.AreEqual(t.Field, u.MyTable.Field);
Assert.AreEqual(t.Value, u.MyTable.Value);
}

[TestMethod]
public void ImplicitOperator_Vector()
{
VectorTable vt = new VectorTable { InnerVector = new[] { "A", "B", "C" } };

TableUnion u = vt;

Assert.AreEqual(u.GetType(), typeof(TableUnion));
Assert.AreEqual(vt.InnerVector, u.VectorTable.InnerVector);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
attribute "fs_serializer";
attribute "fs_valueStruct";

namespace FlatSharpEndToEndTests.UnionImplicitOperator;

struct A { V : uint; }

table MyTable {
Field : string;
Value : uint;
}

struct Vec3 (fs_valueStruct) {
X : uint;
Y : uint;
Z : uint;
}

table VectorTable {
InnerVector : [ string ];
}

union StructUnion { A, Vec3 }

union TableUnion { MyTable, VectorTable }

0 comments on commit cc0659d

Please sign in to comment.