Aigamo.MatchGenerator

RSCG – Aigamo.MatchGenerator    

name Aigamo.MatchGenerator
nuget https://www.nuget.org/packages/Aigamo.MatchGenerator/
link https://github.com/ycanardeau/MatchGenerator
author Aigamo

Generates exhaustive Match() extension methods for enums and abstract record hierarchies (tagged unions), ensuring compile-time safety — all cases must be handled.

How to use

1. Add [GenerateMatch] attribute to an enum or abstract record:

[GenerateMatch]

public enum CarTypes { None, Dacia, Tesla, BMW, Mercedes }

[GenerateMatch]

abstract record MaritalStatus;

sealed record Single : MaritalStatus;

sealed record Married : MaritalStatus;

2. Use the generated .Match() method — all cases required (compile error if any missing):

var msg = car.Match(

onBMW: () => “this is bmw”,

onDacia: () => “this is dacia”,

onMercedes: () => “this is mercedes”,

onNone: () => “this is none”,

onTesla: () => “this is tesla”

);

You can use for Transforming enums/records into exhaustive pattern matching (discriminated unions style).

If a case is missing in Match(), it’s a compile-time error

   

This is how you can use Aigamo.MatchGenerator .

The code that you start with is


<project sdk="Microsoft.NET.Sdk">

  <propertygroup>
    <outputtype>Exe</outputtype>
    <targetframework>net10.0</targetframework>
    <implicitusings>enable</implicitusings>
    <nullable>enable</nullable>
  </propertygroup>

  <propertygroup>
		<emitcompilergeneratedfiles>true</emitcompilergeneratedfiles>
		<compilergeneratedfilesoutputpath>$(BaseIntermediateOutputPath)\GX</compilergeneratedfilesoutputpath>
	</propertygroup>

  <itemgroup>
    <packagereference version="0.0.0-preview013" include="Aigamo.MatchGenerator">
  </packagereference>

  
 

</itemgroup>


The code that you will use is


// See https://aka.ms/new-console-template for more information
using EnumDemo;
using System.Reflection;

Console.WriteLine("Hello, World!");
CarTypes car = CarTypes.BMW;
var message = car.Match(
    onBMW: () =&gt; "this is bmw",
    onDacia: () =&gt; "this is dacia",
    onMercedes: () =&gt; "this is mercedes",
    onNone: () =&gt; "this is none",
    onTesla: () =&gt; "this is tesla"
    );

Console.WriteLine(message);
MaritalStatus maritalStatus = new Divorced();

var messageStatus = maritalStatus.Match(
    onSingle: x =&gt; "single",
    onMarried: x =&gt; "married",
    onDivorced: x =&gt; "divorced",
    onWidowed: x =&gt; "widowed"
);
Console.WriteLine(messageStatus);


using Aigamo.MatchGenerator;
namespace EnumDemo;

[GenerateMatch]
public enum CarTypes 
{
    None,
    Dacia,
    
    Tesla,
    
    BMW,
    
    Mercedes,
}


[GenerateMatch]
abstract record MaritalStatus;

sealed record Single : MaritalStatus;
sealed record Married : MaritalStatus;
sealed record Divorced : MaritalStatus;
sealed record Widowed : MaritalStatus;

   The code that is generated is

// <auto-generated>
using System;
using System.Diagnostics;

namespace EnumDemo;

public static class CarTypesMatchExtensions
{
	public static U Match<u>(
		this CarTypes value,
		Func<u> onBMW,
		Func<u> onDacia,
		Func<u> onMercedes,
		Func<u> onNone,
		Func<u> onTesla
	)
	{
		return value switch
		{
			CarTypes.BMW =&gt; onBMW(),
			CarTypes.Dacia =&gt; onDacia(),
			CarTypes.Mercedes =&gt; onMercedes(),
			CarTypes.None =&gt; onNone(),
			CarTypes.Tesla =&gt; onTesla(),
			_ =&gt; throw new UnreachableException(),
		};
	}
}

using System;

namespace Aigamo.MatchGenerator;

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum)]
internal sealed class GenerateMatchAttribute : Attribute;
// <auto-generated>
using System;
using System.Diagnostics;

namespace EnumDemo;

internal static class MaritalStatusMatchExtensions
{
	public static U Match<u>(
		this MaritalStatus value,
		Func<divorced  , u=""> onDivorced,
		Func<married  , u=""> onMarried,
		Func<single  , u=""> onSingle,
		Func<widowed  , u=""> onWidowed
	)
	{
		return value switch
		{
			Divorced x =&gt; onDivorced(x),
			Married x =&gt; onMarried(x),
			Single x =&gt; onSingle(x),
			Widowed x =&gt; onWidowed(x),
			_ =&gt; throw new UnreachableException(),
		};
	}
}

// <auto-generated>
#nullable enable
using System.Runtime.CompilerServices;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics;
using System.Text.Json;
using System.Text.Json.Serialization;
using TaggedEnum;

namespace EnumDemo;

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public static class EnumDemoCarTypesExtension {
	private static readonly Dictionary<global::enumdemo.cartypes  , string=""> ValueNameMap = new(new EnumDemoCarTypesComparer()) {
		
		{global::EnumDemo.CarTypes.None, "None"},
		{global::EnumDemo.CarTypes.Dacia, "Dacia"},
		{global::EnumDemo.CarTypes.Tesla, "Tesla"},
		{global::EnumDemo.CarTypes.BMW, "BMW"},
		{global::EnumDemo.CarTypes.Mercedes, "Mercedes"},
	};

	

	

	

	

		extension(global::EnumDemo.CarTypes self) {
			public string Data {
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
			get =&gt;
				self switch {
				
			global::EnumDemo.CarTypes.None =&gt; (string)"this is none",
			global::EnumDemo.CarTypes.Dacia =&gt; (string)"this is dacia",
			global::EnumDemo.CarTypes.Tesla =&gt; (string)"this is tesla",
			global::EnumDemo.CarTypes.BMW =&gt; (string)"this is bwm",
			global::EnumDemo.CarTypes.Mercedes =&gt; (string)"this is mercedes",
					_ =&gt; DataNotFoundException.ThrowWithMessage<string>($"Data of {ValueNameMap[self]} not found.")
				};
		}
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
	public static string ToStringFast(this global::EnumDemo.CarTypes self)
	=&gt; self switch {
	
			global::EnumDemo.CarTypes.None =&gt; "None",
			global::EnumDemo.CarTypes.Dacia =&gt; "Dacia",
			global::EnumDemo.CarTypes.Tesla =&gt; "Tesla",
			global::EnumDemo.CarTypes.BMW =&gt; "BMW",
			global::EnumDemo.CarTypes.Mercedes =&gt; "Mercedes",
		_ =&gt; UnreachableException.ThrowWithMessage<string>("Never reach here.")
	};

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
	public static bool HasName(this global::EnumDemo.CarTypes self, string name)
		=&gt; self.ToStringFast() == name;

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
	public static bool HasData(this global::EnumDemo.CarTypes self, string data)
		=&gt; self.Data == data;

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
	public static bool Equals(this global::EnumDemo.CarTypes self, global::EnumDemo.CarTypes v)
		=&gt; self == v;

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
	public static bool TryGetDataByName(string name, [NotNullWhen(true)]out string? v) {
		v = name switch {
		
			"None" =&gt; (string)"this is none",
			"Dacia" =&gt; (string)"this is dacia",
			"Tesla" =&gt; (string)"this is tesla",
			"BMW" =&gt; (string)"this is bwm",
			"Mercedes" =&gt; (string)"this is mercedes",
			_ =&gt; null
		};
		return v is not null;
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
	public static bool TryGetValueByName(string name, [NotNullWhen(true)]out global::EnumDemo.CarTypes? v) {
		v = name switch {
		
			"None" =&gt; global::EnumDemo.CarTypes.None,
			"Dacia" =&gt; global::EnumDemo.CarTypes.Dacia,
			"Tesla" =&gt; global::EnumDemo.CarTypes.Tesla,
			"BMW" =&gt; global::EnumDemo.CarTypes.BMW,
			"Mercedes" =&gt; global::EnumDemo.CarTypes.Mercedes,
			_ =&gt; null
		};
		return v is not null;
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
	public static bool TryGetValueByData(string data, [NotNullWhen(true)]out global::EnumDemo.CarTypes? v) {
		v = data switch {
		
			(string)"this is none" =&gt; global::EnumDemo.CarTypes.None,
			(string)"this is dacia" =&gt; global::EnumDemo.CarTypes.Dacia,
			(string)"this is tesla" =&gt; global::EnumDemo.CarTypes.Tesla,
			(string)"this is bwm" =&gt; global::EnumDemo.CarTypes.BMW,
			(string)"this is mercedes" =&gt; global::EnumDemo.CarTypes.Mercedes,
			_ =&gt; null
		};
		return v is not null;
	}
}

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
internal sealed class EnumDemoCarTypesComparer: IEqualityComparer<global::enumdemo.cartypes> {
	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public bool Equals(global::EnumDemo.CarTypes x, global::EnumDemo.CarTypes y) =&gt; x == y;

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public int GetHashCode([DisallowNull] global::EnumDemo.CarTypes obj) =&gt; (int)obj;
}

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
internal sealed class EnumDemoCarTypesstringComparer: IEqualityComparer<string> {
	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public bool Equals(string? x, string? y) =&gt; x == y;

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public int GetHashCode([DisallowNull] string obj) =&gt; obj.GetHashCode();
}

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class EnumDemoCarTypesToDataConverter: JsonConverter<global::enumdemo.cartypes> {
	public override global::EnumDemo.CarTypes Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
		string? token = reader.GetString();
		return 	string.IsNullOrEmpty(token)
	? JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't convert data \"{token}\" to global::EnumDemo.CarTypes.")
	: EnumDemoCarTypesExtension.TryGetValueByData(token, out var result)
		? result.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{token}\" in global::EnumDemo.CarTypes data.");
	}

	public override void Write(Utf8JsonWriter writer, global::EnumDemo.CarTypes value, JsonSerializerOptions options) {
		writer.WriteStringValue(value.Data);
	}
}

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class EnumDemoCarTypesArrayToDataArrayConverter: JsonConverter<global::enumdemo.cartypes  &#91;&#93;> {
	public override global::EnumDemo.CarTypes[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
		var list = new List<global::enumdemo.cartypes>();
		while (reader.Read()) {
			switch (reader.TokenType) {
				case JsonTokenType.StartArray:
					continue;
				case JsonTokenType.EndArray:
					goto label;
				case JsonTokenType.String:
					var v = reader.GetString() is not {} token ? UnreachableException.ThrowWithMessage<string>("JsonTokenType is string but reader.GetString() is null.") : token;
					list.Add(EnumDemoCarTypesExtension.TryGetValueByData(
						v,
						out var item)
						? item!.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{v}\" in global::EnumDemo.CarTypes data."));
					continue;
				default:
					continue;
			}
		}
		label:
		return list.ToArray();
	}

	public override void Write(Utf8JsonWriter writer, global::EnumDemo.CarTypes[] arr, JsonSerializerOptions options) {
		writer.WriteStartArray();
		for (int i = 0, len = arr.Length; i &lt; len; ++i) {
			writer.WriteStringValue(arr[i].Data);
		}
		writer.WriteEndArray();
	}
}

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class NullableEnumDemoCarTypesArrayToDataArrayConverter: JsonConverter<global::enumdemo.cartypes  ?&#91;&#93;> {
	public override global::EnumDemo.CarTypes?[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
		var list = new List<global::enumdemo.cartypes  ?>();
		while (reader.Read()) {
			switch (reader.TokenType) {
				case JsonTokenType.StartArray:
					continue;
				case JsonTokenType.EndArray:
					goto label;
				case JsonTokenType.Null:
					list.Add(null);
					continue;
				case JsonTokenType.String:
					var v = reader.GetString() is not {} token ? UnreachableException.ThrowWithMessage<string>("JsonTokenType is string but reader.GetString() is null.") : token;
					list.Add(EnumDemoCarTypesExtension.TryGetValueByData(
						v,
						out var item)
						? item!.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{v}\" in global::EnumDemo.CarTypes data."));
					continue;
				default:
					continue;
			}
		}
		label:
		return list.ToArray();
	}

	public override void Write(Utf8JsonWriter writer, global::EnumDemo.CarTypes?[] arr, JsonSerializerOptions options) {
		writer.WriteStartArray();
		for (int i = 0, len = arr.Length; i &lt; len; ++i) {
			var v = arr[i];
			if (v is null) {
				writer.WriteNullValue();
			} else {
				writer.WriteStringValue(v.Value.Data);
			}

		}
		writer.WriteEndArray();
	}
}

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class EnumDemoCarTypesEnumerableToDataEnumerableConverter: JsonConverter<ienumerable><global::enumdemo.cartypes>&gt; {
	public override IEnumerable<global::enumdemo.cartypes> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
		var list = new List<global::enumdemo.cartypes>();
		while (reader.Read()) {
			switch (reader.TokenType) {
				case JsonTokenType.StartArray:
					continue;
				case JsonTokenType.EndArray:
					goto label;
				case JsonTokenType.String:
					var v = reader.GetString() is not {} token ? UnreachableException.ThrowWithMessage<string>("JsonTokenType is string but reader.GetString() is null.") : token;
					list.Add(EnumDemoCarTypesExtension.TryGetValueByData(
						v,
						out var item)
						? item!.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{v}\" in global::EnumDemo.CarTypes data."));
					continue;
				default:
					continue;
			}
		}
		label:
		return list.ToArray();
	}

	public override void Write(Utf8JsonWriter writer, IEnumerable<global::enumdemo.cartypes> values, JsonSerializerOptions options) {
		writer.WriteStartArray();
		foreach (var v in values) {
			writer.WriteStringValue(v.Data);
		}
		writer.WriteEndArray();
	}
}

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class NullableEnumDemoCarTypesEnumerableToDataEnumerableConverter: JsonConverter<ienumerable><global::enumdemo.cartypes  ?>&gt; {
	public override IEnumerable<global::enumdemo.cartypes  ?> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
		var list = new List<global::enumdemo.cartypes  ?>();
		while (reader.Read()) {
			switch (reader.TokenType) {
				case JsonTokenType.StartArray:
					continue;
				case JsonTokenType.EndArray:
					goto label;
				case JsonTokenType.Null:
					list.Add(null);
					continue;
				case JsonTokenType.String:
					var v = reader.GetString() is not {} token ? UnreachableException.ThrowWithMessage<string>("JsonTokenType is string but reader.GetString() is null.") : token;
					list.Add(EnumDemoCarTypesExtension.TryGetValueByData(
						v,
						out var item)
						? item!.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{v}\" in global::EnumDemo.CarTypes data."));
					continue;
				default:
					continue;
			}
		}
		label:
		return list.ToArray();
	}

	public override void Write(Utf8JsonWriter writer, IEnumerable<global::enumdemo.cartypes  ?> values, JsonSerializerOptions options) {
		writer.WriteStartArray();
		foreach (var v in values) {
			if (v is null) {
				writer.WriteNullValue();
			} else {
				writer.WriteStringValue(v.Value.Data);
			}
		}
		writer.WriteEndArray();
	}
}

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class EnumDemoCarTypesToNameConverter: JsonConverter<global::enumdemo.cartypes> {
	public override global::EnumDemo.CarTypes Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
		string? token = reader.GetString();
		return string.IsNullOrEmpty(token)
			? JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't convert name \"{token}\" to global::EnumDemo.CarTypes.")
			: EnumDemoCarTypesExtension.TryGetValueByName(token, out var result)
				? result.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{token}\" in global::EnumDemo.CarTypes name.");
	}

	public override void Write(Utf8JsonWriter writer, global::EnumDemo.CarTypes value, JsonSerializerOptions options) {
		writer.WriteStringValue(value.ToStringFast());
	}
}

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class EnumDemoCarTypesArrayToNameArrayConverter: JsonConverter<global::enumdemo.cartypes  &#91;&#93;> {
	public override global::EnumDemo.CarTypes[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
		var list = new List<global::enumdemo.cartypes>();
		while (reader.Read()) {
			switch (reader.TokenType) {
				case JsonTokenType.StartArray:
					continue;
				case JsonTokenType.EndArray:
					goto label;
				case JsonTokenType.String:
					var v = reader.GetString() is not {} token ? UnreachableException.ThrowWithMessage<string>("JsonTokenType is string but reader.GetString() is null.") : token;
					list.Add(EnumDemoCarTypesExtension.TryGetValueByName(
						v,
						out var item)
						? item!.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{v}\" in global::EnumDemo.CarTypes name."));
					continue;
				default:
					continue;
			}
		}
		label:
		return list.ToArray();
	}

	public override void Write(Utf8JsonWriter writer, global::EnumDemo.CarTypes[] arr, JsonSerializerOptions options) {
		writer.WriteStartArray();
		for (int i = 0, len = arr.Length; i &lt; len; ++i) {
			writer.WriteStringValue(arr[i].ToStringFast());
		}
		writer.WriteEndArray();
	}
}

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class NullableEnumDemoCarTypesArrayToNameArrayConverter: JsonConverter<global::enumdemo.cartypes  ?&#91;&#93;> {
	public override global::EnumDemo.CarTypes?[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
		var list = new List<global::enumdemo.cartypes  ?>();
		while (reader.Read()) {
			switch (reader.TokenType) {
				case JsonTokenType.StartArray:
					continue;
				case JsonTokenType.EndArray:
					goto label;
				case JsonTokenType.Null:
					list.Add(null);
					continue;
				case JsonTokenType.String:
					var v = reader.GetString() is not {} token ? UnreachableException.ThrowWithMessage<string>("JsonTokenType is string but reader.GetString() is null.") : token;
					list.Add(EnumDemoCarTypesExtension.TryGetValueByName(
						v,
						out var item)
						? item!.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{v}\" in global::EnumDemo.CarTypes name."));
					continue;
				default:
					continue;
			}
		}
		label:
		return list.ToArray();
	}

	public override void Write(Utf8JsonWriter writer, global::EnumDemo.CarTypes?[] arr, JsonSerializerOptions options) {
		writer.WriteStartArray();
		for (int i = 0, len = arr.Length; i &lt; len; ++i) {
			var v = arr[i];
			if (v is null) {
				writer.WriteNullValue();
			} else {
				writer.WriteStringValue(v.Value.ToStringFast());
			}
		}
		writer.WriteEndArray();
	}
}

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class EnumDemoCarTypesEnumerableToNameEnumerableConverter: JsonConverter<ienumerable><global::enumdemo.cartypes>&gt; {
	public override IEnumerable<global::enumdemo.cartypes> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
		var list = new List<global::enumdemo.cartypes>();
		while (reader.Read()) {
			switch (reader.TokenType) {
				case JsonTokenType.StartArray:
					continue;
				case JsonTokenType.EndArray:
					goto label;
				case JsonTokenType.String:
					var v = reader.GetString() is not {} token ? UnreachableException.ThrowWithMessage<string>("JsonTokenType is string but reader.GetString() is null.") : token;
					list.Add(EnumDemoCarTypesExtension.TryGetValueByName(
						v,
						out var item)
						? item!.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{v}\" in global::EnumDemo.CarTypes name."));
					continue;
				default:
					continue;
			}
		}
		label:
		return list.ToArray();
	}

	public override void Write(Utf8JsonWriter writer, IEnumerable<global::enumdemo.cartypes> values, JsonSerializerOptions options) {
		writer.WriteStartArray();
		foreach (var v in values) {
			writer.WriteStringValue(v.ToStringFast());
		}
		writer.WriteEndArray();
	}
}

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class NullableEnumDemoCarTypesEnumerableToNameEnumerableConverter: JsonConverter<ienumerable><global::enumdemo.cartypes  ?>&gt; {
	public override IEnumerable<global::enumdemo.cartypes  ?> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
		var list = new List<global::enumdemo.cartypes  ?>();
		while (reader.Read()) {
			switch (reader.TokenType) {
				case JsonTokenType.StartArray:
					continue;
				case JsonTokenType.EndArray:
					goto label;
				case JsonTokenType.Null:
					list.Add(null);
					continue;
				case JsonTokenType.String:
					var v = reader.GetString() is not {} token ? UnreachableException.ThrowWithMessage<string>("JsonTokenType is string but reader.GetString() is null.") : token;
					list.Add(EnumDemoCarTypesExtension.TryGetValueByName(
						v,
						out var item)
						? item!.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{v}\" in global::EnumDemo.CarTypes name."));
					continue;
				default:
					continue;
			}
		}
		label:
		return list.ToArray();
	}

	public override void Write(Utf8JsonWriter writer, IEnumerable<global::enumdemo.cartypes  ?> values, JsonSerializerOptions options) {
		writer.WriteStartArray();
		foreach (var v in values) {
			if (v is null) {
				writer.WriteNullValue();
			} else {
				writer.WriteStringValue(v.Value.ToStringFast());
			}
		}
		writer.WriteEndArray();
	}
}

// <auto-generated>
#nullable enable

using System.Text.Json;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;

namespace TaggedEnum;

internal static class JsonExceptionExtensions {
	extension(JsonException) {
		[DoesNotReturn]
		public static T ThrowWithMessage<t>(string msg)
			=&gt; throw new JsonException(msg);
	}
}

internal static class UnreachableExceptionExtensions {
	extension(UnreachableException) {
		[DoesNotReturn]
		public static T ThrowWithMessage<t>(string msg)
			=&gt; throw new UnreachableException(msg);
	}
}

#pragma warning disable CA1050 // Declare types in namespaces
[AttributeUsage(
	AttributeTargets.Field,
	Inherited = false,
	AllowMultiple = false
	)]
internal sealed class Data<tvalue>(TValue v): Attribute {
	public TValue V { get; private set; } = v;
}

[AttributeUsage(
	AttributeTargets.Field,
	Inherited = false,
	AllowMultiple = false
	)]
// TValue default is string
internal sealed class Data: Attribute {
	public object? V { get; }

	public Data(object str) {
		V = str;
	}

	public Data() {}
}
#pragma warning restore CA1050 // Declare types in namespaces

#pragma warning disable CA1050 // Declare types in namespaces
[AttributeUsage(
	AttributeTargets.Enum,
	Inherited = false,
	AllowMultiple = false
	)]
internal sealed class Tagged<tvalue>: Attribute {
	public bool Inline = true;

	public bool UseSwitch = true;

	public bool AllowDuplicate = false;
}

[AttributeUsage(
	AttributeTargets.Enum,
	Inherited = false,
	AllowMultiple = false
	)]
// TValue default is string
internal sealed class Tagged: Attribute {
		public bool UseAll = false;

	public bool Inline = true;

	public bool UseSwitch = true;

	public bool AllowDuplicate = false;
}
#pragma warning restore CA1050 // Declare types in namespaces

public sealed class DataNotFoundException(string msg): Exception(msg) {
	[DoesNotReturn]
	public static T ThrowWithMessage<t>(string message) =&gt; throw new DataNotFoundException(message);
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Aigamo.MatchGenerator


Posted

in

,

by

Tags: