Skip to content

Commit

Permalink
Add sample for deserializing inline union (#147)
Browse files Browse the repository at this point in the history
  • Loading branch information
agocke authored Dec 25, 2023
1 parent d4ee595 commit 08ae46b
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Unions Sample",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/artifacts/bin/Unions/debug/Unions.dll",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": ".NET Core Launch (console)",
"type": "coreclr",
Expand Down
129 changes: 129 additions & 0 deletions samples/unions/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
using System.Runtime.Serialization;
using Serde;
using Serde.Json;

var json = """
{ "bar": { "_t": "Bar1", "bar": 1 } }
""";
var bar = JsonSerializer.Deserialize<Foo>(json);
Console.WriteLine(bar);

[GenerateDeserialize]
partial class Foo {
public required AbstractBar bar;
}

[GenerateDeserialize]
partial class Bar1 : AbstractBar {
public int bar;
}

[GenerateSerde]
partial class Bar2 : AbstractBar {
public double bar;
}

abstract partial class AbstractBar : IDeserialize<AbstractBar>
{
static AbstractBar IDeserialize<AbstractBar>.Deserialize<D>(ref D deserializer)
{
var visitor = new SerdeVisitor(deserializer);
var fieldNames = new[]
{
"bar"
};
return deserializer.DeserializeType<AbstractBar, SerdeVisitor>("AbstractBar", fieldNames, visitor);
}

private sealed class SerdeVisitor : IDeserializeVisitor<AbstractBar>
{
private readonly IDeserializer _deserializer;
public SerdeVisitor(IDeserializer deserializer)
{
_deserializer = deserializer;
}

public string ExpectedTypeName => "AbstractBar";

AbstractBar IDeserializeVisitor<AbstractBar>.VisitDictionary<D>(ref D d)
{
var result = d.TryGetNextKey<string, StringWrap>(out string? key);
if (!result || key != "_t")
{
throw new InvalidDeserializeValueException("Expected a _t field");
}
var value = d.GetNextValue<string, StringWrap>();
var inline = new InlineDeserializer(_deserializer, d);
switch (value)
{
case "Bar1":
var bar1 = InlineDeserialize<Bar1>(inline);
return bar1;
case "Bar2":
var bar2 = InlineDeserialize<Bar2>(inline);
return bar2;
default:
throw new InvalidDeserializeValueException($"Unexpected value {value}");
}
}

private static T InlineDeserialize<T>(IDeserializer deserializer) where T : IDeserialize<T>
{
return T.Deserialize(ref deserializer);
}
}

private class InlineDeserializer : IDeserializer
{
private readonly IDeserializer _deserializer;
private IDeserializeDictionary _deserializeDictionary;

public InlineDeserializer(IDeserializer deserializer, IDeserializeDictionary deserializeDictionary)
{
_deserializer = deserializer;
_deserializeDictionary = deserializeDictionary;
}

public T DeserializeAny<T, V>(V v) where V : IDeserializeVisitor<T> => throw new NotImplementedException();

public T DeserializeBool<T, V>(V v) where V : IDeserializeVisitor<T> => throw new NotImplementedException();

public T DeserializeByte<T, V>(V v) where V : IDeserializeVisitor<T> => throw new NotImplementedException();

public T DeserializeChar<T, V>(V v) where V : IDeserializeVisitor<T> => throw new NotImplementedException();

public T DeserializeDecimal<T, V>(V v) where V : IDeserializeVisitor<T> => throw new NotImplementedException();

public T DeserializeDictionary<T, V>(V v) where V : IDeserializeVisitor<T>
=> v.VisitDictionary(ref _deserializeDictionary);

public T DeserializeDouble<T, V>(V v) where V : IDeserializeVisitor<T> => throw new NotImplementedException();

public T DeserializeEnumerable<T, V>(V v) where V : IDeserializeVisitor<T> => throw new NotImplementedException();

public T DeserializeFloat<T, V>(V v) where V : IDeserializeVisitor<T> => throw new NotImplementedException();

public T DeserializeI16<T, V>(V v) where V : IDeserializeVisitor<T> => throw new NotImplementedException();

public T DeserializeI32<T, V>(V v) where V : IDeserializeVisitor<T> => throw new NotImplementedException();

public T DeserializeI64<T, V>(V v) where V : IDeserializeVisitor<T> => throw new NotImplementedException();

public T DeserializeIdentifier<T, V>(V v) where V : IDeserializeVisitor<T> => throw new NotImplementedException();

public T DeserializeNullableRef<T, V>(V v) where V : IDeserializeVisitor<T> => throw new NotImplementedException();

public T DeserializeSByte<T, V>(V v) where V : IDeserializeVisitor<T> => throw new NotImplementedException();

public T DeserializeString<T, V>(V v) where V : IDeserializeVisitor<T> => throw new NotImplementedException();

public T DeserializeType<T, V>(string typeName, ReadOnlySpan<string> fieldNames, V v) where V : IDeserializeVisitor<T>
=> DeserializeDictionary<T, V>(v);

public T DeserializeU16<T, V>(V v) where V : IDeserializeVisitor<T> => throw new NotImplementedException();

public T DeserializeU32<T, V>(V v) where V : IDeserializeVisitor<T> => throw new NotImplementedException();

public T DeserializeU64<T, V>(V v) where V : IDeserializeVisitor<T> => throw new NotImplementedException();
}
}
14 changes: 14 additions & 0 deletions samples/unions/Unions.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="../../src/serde/Serde.csproj" />
<ProjectReference Include="../../src/generator/SerdeGenerator.csproj" OutputItemType="Analyzer" />
</ItemGroup>
</Project>
17 changes: 17 additions & 0 deletions serde-dn.sln
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serde", "src\serde\Serde.cs
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serde.Generation.Test", "test\Serde.Generation.Test\Serde.Generation.Test.csproj", "{382F0F9B-7B6C-439A-96B4-BFCF433FB611}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{77AF753A-9C1B-447C-AF13-7FFBE57A446F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unions", "samples\unions\Unions.csproj", "{0637752A-864A-47DC-BD88-8B9636D67529}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -87,6 +91,18 @@ Global
{382F0F9B-7B6C-439A-96B4-BFCF433FB611}.Release|x64.Build.0 = Release|Any CPU
{382F0F9B-7B6C-439A-96B4-BFCF433FB611}.Release|x86.ActiveCfg = Release|Any CPU
{382F0F9B-7B6C-439A-96B4-BFCF433FB611}.Release|x86.Build.0 = Release|Any CPU
{0637752A-864A-47DC-BD88-8B9636D67529}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0637752A-864A-47DC-BD88-8B9636D67529}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0637752A-864A-47DC-BD88-8B9636D67529}.Debug|x64.ActiveCfg = Debug|Any CPU
{0637752A-864A-47DC-BD88-8B9636D67529}.Debug|x64.Build.0 = Debug|Any CPU
{0637752A-864A-47DC-BD88-8B9636D67529}.Debug|x86.ActiveCfg = Debug|Any CPU
{0637752A-864A-47DC-BD88-8B9636D67529}.Debug|x86.Build.0 = Debug|Any CPU
{0637752A-864A-47DC-BD88-8B9636D67529}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0637752A-864A-47DC-BD88-8B9636D67529}.Release|Any CPU.Build.0 = Release|Any CPU
{0637752A-864A-47DC-BD88-8B9636D67529}.Release|x64.ActiveCfg = Release|Any CPU
{0637752A-864A-47DC-BD88-8B9636D67529}.Release|x64.Build.0 = Release|Any CPU
{0637752A-864A-47DC-BD88-8B9636D67529}.Release|x86.ActiveCfg = Release|Any CPU
{0637752A-864A-47DC-BD88-8B9636D67529}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -99,5 +115,6 @@ Global
{A5391F09-58A5-4E83-9EB1-755B9CEB1812} = {278C5DCE-D96F-46AC-8865-622418F28A8D}
{2411C763-490C-4384-AD87-AD9643946F55} = {C29CDEE5-5D85-496E-8E43-27A474AF8AEB}
{382F0F9B-7B6C-439A-96B4-BFCF433FB611} = {278C5DCE-D96F-46AC-8865-622418F28A8D}
{0637752A-864A-47DC-BD88-8B9636D67529} = {77AF753A-9C1B-447C-AF13-7FFBE57A446F}
EndGlobalSection
EndGlobal

0 comments on commit 08ae46b

Please sign in to comment.