Matches.SourceGeneration 2.1.0

dotnet add package Matches.SourceGeneration --version 2.1.0
                    
NuGet\Install-Package Matches.SourceGeneration -Version 2.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Matches.SourceGeneration" Version="2.1.0">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Matches.SourceGeneration" Version="2.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Matches.SourceGeneration">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Matches.SourceGeneration --version 2.1.0
                    
#r "nuget: Matches.SourceGeneration, 2.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Matches.SourceGeneration@2.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Matches.SourceGeneration&version=2.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Matches.SourceGeneration&version=2.1.0
                    
Install as a Cake Tool

Matches.SourceGeneration

A C# source generator that automatically creates discriminated union types and Match methods from enums.

Usage

The library provides two attributes:

  • [DiscriminatedUnion] – marks an enum as a discriminated union.
  • [DiscriminatedUnionCase] – assigns a type to an enum case.

When the project is built, interfaces, records, and helper methods are generated automatically.


Example: Simple types

Mark the ContactKind enum as a discriminated union and assign types to its cases:

[DiscriminatedUnion]
public enum ContactKind
{
    [DiscriminatedUnionCase(typeof(Email))]
    Email,

    [DiscriminatedUnionCase(typeof(Phone))]
    Phone,

    [DiscriminatedUnionCase(typeof(WebHook))]
    WebHook
}

Generated on build:

  • IContact interface
  • EmailContact, PhoneContact, and WebHookContact records
  • Contact static class with factory and Match methods

Usage example:

const string message = "hmm";

IContact[] contacts =
[
    Contact.GetEmailContact(new Email("aaa@bbb.com")),
    Contact.GetPhoneContact(new Phone(380, 1234567)),
    Contact.GetWebHookContact(new WebHook(new Uri("https://okak.kot")))
];

foreach (var contact in contacts)
{
    var res = SendMessage(contact, message);
    Console.WriteLine(res);
}

static string SendMessage(IContact contact, string text) =>
    Contact.Match
    (
        contact,
        email   => $"'{text}' sent to {email.Address} email address",
        phone   => $"'{text}' sent to +{phone.Code}{phone.Number} phone number",
        webHook => $"'{text}' sent to {webHook.Uri} webhook URI"
    );

Output:

'hmm' sent to aaa@bbb.com email address
'hmm' sent to +3801234567 phone number
'hmm' sent to https://okak.kot/ webhook URI

Example: Generic types

Bound generic types are supported the same way as simple ones.

To generate types with generic parameters, specify the unbound generic type and provide arguments in order:

  • a concrete type → binds the parameter
  • null or GenericPlaceholder → keeps it as a generic parameter in the generated type
[DiscriminatedUnion]
public enum WebRequestResultKind
{
    [DiscriminatedUnionCase(typeof(RequestData<,,>), typeof(string), null, typeof(GenericPlaceholder))]
    Success,

    [DiscriminatedUnionCase(typeof(List<>), (Type?)null)]
    Warnings,

    [DiscriminatedUnionCase(typeof(List<string>))]
    Errors
}

public record RequestData<TKey, TData, TItem>(TData Data) 
    where TData : IDictionary<TKey, TItem> 
    where TItem : struct;

public record WarningInfo(int Code, string Message);

More examples

Check out the Matches.Tests project for additional usage patterns.


License

This project is dedicated to the public domain under the Unlicense.
See the LICENSE file for details.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.1.0 137 9/30/2025
2.0.5 150 9/25/2025