RSCG – UnionGen
name | UnionGen |
nuget | https://www.nuget.org/packages/UnionGen/ |
link | https://github.com/markushaslinger/union_source_generator |
author | M. Haslinger |
Generating unions between types
This is how you can use UnionGen .
The code that you start with is
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <PropertyGroup> <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath> </PropertyGroup> <ItemGroup> <PackageReference Include="UnionGen" Version="1.4.0" /> </ItemGroup> </Project>
The code that you will use is
using UnionTypesDemo; Console.WriteLine("Save or not"); var data = SaveToDatabase.Save(0); Console.WriteLine(data.IsNotFound); data = SaveToDatabase.Save(1); Console.WriteLine(data.IsResultOfInt32); Console.WriteLine(data.AsResultOfInt32());
using UnionGen.Types; using UnionGen; namespace UnionTypesDemo; [Union<Result<int>, NotFound>] public partial struct ResultSave { }
using UnionGen.Types; namespace UnionTypesDemo; public class SaveToDatabase { public static ResultSave Save(int i) { if(i ==0) { return new NotFound(); } return new Result<int>(i); } }
The code that is generated is
// <auto-generated by UnionSourceGen /> #nullable enable using System; namespace UnionTypesDemo { public readonly partial struct ResultSave : IEquatable<ResultSave> { private readonly UnionGen.Types.Result<int> _value0; private readonly UnionGen.Types.NotFound _value1; private readonly UnionGen.InternalUtil.StateByte _state; private ResultSave(int index, int actualTypeIndex) { _state = new UnionGen.InternalUtil.StateByte(index, actualTypeIndex); } public ResultSave(UnionGen.Types.Result<int> value): this(0, 0) { _value0 = value; } public ResultSave(UnionGen.Types.NotFound value): this(1, 1) { _value1 = value; } [Obsolete(UnionGen.InternalUtil.UnionGenInternalConst.DefaultConstructorWarning, true)] public ResultSave(): this(0, 0) {} public bool IsResultOfInt32 => _state.Index == 0; public bool IsNotFound => _state.Index == 1; public UnionGen.Types.Result<int> AsResultOfInt32() => IsResultOfInt32 ? _value0 : throw UnionGen.InternalUtil.ExceptionHelper.ThrowNotOfType(GetTypeName(0), GetTypeName(_state.ActualTypeIndex)); public UnionGen.Types.NotFound AsNotFound() => IsNotFound ? _value1 : throw UnionGen.InternalUtil.ExceptionHelper.ThrowNotOfType(GetTypeName(1), GetTypeName(_state.ActualTypeIndex)); public static implicit operator ResultSave(UnionGen.Types.Result<int> value) => new ResultSave(value); public static implicit operator ResultSave(UnionGen.Types.NotFound value) => new ResultSave(value); public static bool operator ==(ResultSave left, ResultSave right) => left.Equals(right); public static bool operator !=(ResultSave left, ResultSave right) => !left.Equals(right); public TResult Match<TResult>(Func<UnionGen.Types.Result<int>, TResult> withResultOfInt32, Func<UnionGen.Types.NotFound, TResult> withNotFound) => _state.ActualTypeIndex switch { 0 => withResultOfInt32(_value0), 1 => withNotFound(_value1), _ => throw UnionGen.InternalUtil.ExceptionHelper.ThrowUnknownTypeIndex(_state.ActualTypeIndex) }; public void Switch(Action<UnionGen.Types.Result<int>> forResultOfInt32, Action<UnionGen.Types.NotFound> forNotFound) { switch (_state.ActualTypeIndex) { case 0: forResultOfInt32(_value0); break; case 1: forNotFound(_value1); break; default: throw UnionGen.InternalUtil.ExceptionHelper.ThrowUnknownTypeIndex(_state.ActualTypeIndex); } } public override string ToString() => _state.Index switch { 0 => _value0.ToString()!, 1 => _value1.ToString()!, _ => throw UnionGen.InternalUtil.ExceptionHelper.ThrowUnknownTypeIndex(_state.Index) }; public bool Equals(ResultSave other) => _state.Index == other._state.Index && _state.Index switch { 0 => _value0.Equals(other._value0), 1 => _value1.Equals(other._value1), _ => false }; public override bool Equals(object? obj) { if (ReferenceEquals(null, obj)) { return false; } return obj is ResultSave other && Equals(other); } public override int GetHashCode(){ unchecked { var hash = _state.Index switch { 0 => _value0.GetHashCode(), 1 => _value1.GetHashCode(), _ => 0 }; return (hash * 397) ^ _state.Index; } } public string GetTypeName(int index) => index switch { 0 => "UnionGen.Types.Result<int>", 1 => "UnionGen.Types.NotFound", _ => throw UnionGen.InternalUtil.ExceptionHelper.ThrowUnknownTypeIndex(index) }; } }
Code and pdf at
https://ignatandrei.github.io/RSCG_Examples/v2/docs/UnionGen
Leave a Reply