Skip to content

tomwolanski/TaggedUnionGenerator

Repository files navigation

TaggedUnionGenerator

A simple code generator to produce a tagged discriminated unions.

Example usage:

namespace NS;

using TaggedUnion;
using TaggedUnion.Json;


// define a union with 2 options. 
[UnionOption<int>("IntegerVal")]
[UnionOption<bool>("BooleanVal")]
public partial struct IntOrBool
{ }


// optionally, define a System.Text.Json converter class
[UnionJsonConverterAttribute<IntOrBool>]
public partial class IntOrBoolJsonSerializer
{ }


public static class Program
{
    public static void Main()
    {
        // create a union with factory method
        IntOrBool value = IntOrBool.FromBooleanVal(false);


        // create a union using implicit cast operator
        value = 2;


        // test whitch option the union stores
        if (value.Type == IntOrBool.TypeEnum.BooleanVal)
        {
            Console.WriteLine($"it is a boolean!");
        }


        // transform value of the union
        var matched = value.Match<string>(
            onBooleanVal: v => $"got boolean value {v}",
            onIntegerVal: v => $"got integer value {v}");

        Console.WriteLine(matched);


        // act on the value of the union
        value.Switch(
            onBooleanVal: v => Console.WriteLine($"got boolean value {v}"),
            onIntegerVal: v => Console.WriteLine($"got integer value {v}"));


        // attempt to pick one of the option
        if (value.TryGetIntegerVal(out var v))
        {
            Console.WriteLine($"it is an integer of value {v}!");
        }


        // Json serialization using System.Text.Json
        var ops = new JsonSerializerOptions();
        ops.Converters.Add(new IntOrBoolJsonSerializer()); // new serializer that is generated
        ops.Converters.Add(new System.Text.Json.Serialization.JsonStringEnumConverter());  // current union type is stored as an enum, so we can serialize it as a string too;
        ops.WriteIndented = true;

        var json = JsonSerializer.Serialize(value, ops);
        var deserialized = JsonSerializer.Deserialize<IntOrBool>(json, ops);
    }
}

VS linting support

Detect empty option name.

All options require name, so the values like empty string or null cannot be provided. image

Detect multiple options using the sme name.

In this scenario the generator is unable to produce methods with the same name, so an error is produced: image

Detect multiple options using the same CRL type.

In this scenario the generator skips generation of cast operators since wo would not be able to decide whenever the value should be matched to which factory method. image

Detect invalid usage of JSON converter attrubute.

A UnionJsonConverterAttribute<> requires a type to be a valid union with options, so invalid usage fails the build. image

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages