RSCG – Funcky.DiscriminatedUnion
RSCG – Funcky.DiscriminatedUnion
name | Funcky.DiscriminatedUnion |
nuget | https://www.nuget.org/packages/Funcky.DiscriminatedUnion/ |
link | https://github.com/polyadic/funcky-discriminated-union |
author | Polyadic |
Generating discriminated unions for C# 9.0 and above.
This is how you can use Funcky.DiscriminatedUnion .
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> <ItemGroup> <PackageReference Include="Funcky.DiscriminatedUnion" Version="1.1.0" /> </ItemGroup> <PropertyGroup> <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath> </PropertyGroup> </Project>
The code that you will use is
using Union; Console.WriteLine("Save or not"); var data = SaveToDatabase.Save(0); Console.WriteLine(data.Match(ok => true, error => false)); data = SaveToDatabase.Save(1); Console.WriteLine(data.Match(ok => true, error => false));
namespace Union; [Funcky.DiscriminatedUnion] public abstract partial record ResultSave { public partial record Success(int Value): ResultSave; public partial record ValidationError(string Message):ResultSave; //public sealed partial record Ok(T Value) : ResultSave<T>; //public sealed partial record Error(Exception Exception) : ResultSave<T>; }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Union; internal class SaveToDatabase { public static ResultSave Save(int i) { if (i == 0) { return new ResultSave.ValidationError(" cannot save 0"); } return new ResultSave.Success(i); } }
The code that is generated is
// <auto-generated/> #nullable enable namespace Funcky { [global::System.Diagnostics.Conditional("Funcky_DiscriminatedUnion")] [global::System.AttributeUsage(global::System.AttributeTargets.Class)] internal sealed class DiscriminatedUnionAttribute : global::System.Attribute { /// <summary>Allow only consumers in the same assembly to use the exhaustive <c>Match</c> and <c>Switch</c> methods.</summary> public bool NonExhaustive { get; set; } /// <summary>Generates exhaustive <c>Match</c> and <c>Switch</c> methods for the entire type hierarchy.</summary> public bool Flatten { get; set; } /// <summary>Customized the generic type name used for the result in the generated <c>Match</c> methods. Defaults to <c>TResult</c>.</summary> public string? MatchResultTypeName { get; set; } } }
// <auto-generated/> #nullable enable namespace Union { partial record ResultSave { [global::System.CodeDom.Compiler.GeneratedCode("Funcky.DiscriminatedUnion.SourceGeneration", "1.1.0.0")] public abstract TResult Match<TResult>(global::System.Func<Success, TResult> success, global::System.Func<ValidationError, TResult> validationError); [global::System.CodeDom.Compiler.GeneratedCode("Funcky.DiscriminatedUnion.SourceGeneration", "1.1.0.0")] public abstract void Switch(global::System.Action<Success> success, global::System.Action<ValidationError> validationError); partial record Success { [global::System.CodeDom.Compiler.GeneratedCode("Funcky.DiscriminatedUnion.SourceGeneration", "1.1.0.0")] public override TResult Match<TResult>(global::System.Func<Success, TResult> success, global::System.Func<ValidationError, TResult> validationError) => success(this); [global::System.CodeDom.Compiler.GeneratedCode("Funcky.DiscriminatedUnion.SourceGeneration", "1.1.0.0")] public override void Switch(global::System.Action<Success> success, global::System.Action<ValidationError> validationError) => success(this); } partial record ValidationError { [global::System.CodeDom.Compiler.GeneratedCode("Funcky.DiscriminatedUnion.SourceGeneration", "1.1.0.0")] public override TResult Match<TResult>(global::System.Func<Success, TResult> success, global::System.Func<ValidationError, TResult> validationError) => validationError(this); [global::System.CodeDom.Compiler.GeneratedCode("Funcky.DiscriminatedUnion.SourceGeneration", "1.1.0.0")] public override void Switch(global::System.Action<Success> success, global::System.Action<ValidationError> validationError) => validationError(this); } } }
Code and pdf at
https://ignatandrei.github.io/RSCG_Examples/v2/docs/Funcky.DiscriminatedUnion
Leave a Reply