https://github.com/OhFlowi/FusionReactor.SourceGenerators.EnumExtensions
https://github.com/OhFlowi/FusionReactor.SourceGenerators.EnumExtensions
Last synced: 3 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/OhFlowi/FusionReactor.SourceGenerators.EnumExtensions
- Owner: OhFlowi
- License: mit
- Created: 2024-04-02T18:54:31.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-03-12T23:20:33.000Z (4 months ago)
- Last Synced: 2025-04-13T20:51:55.393Z (3 months ago)
- Language: C#
- Size: 141 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- RSCG_Examples - https://github.com/OhFlowi/FusionReactor.SourceGenerators.EnumExtensions
README
[](https://raw.githubusercontent.com/OhFlowi/FusionReactor.SourceGenerators.EnumExtensions/master/LICENSE)
[](https://www.nuget.org/packages/FusionReactor.SourceGenerators.EnumExtensions)
[](https://www.nuget.org/packages/FusionReactor.SourceGenerators.EnumExtensions)# FusionReactor.SourceGenerators.EnumExtensions
A C# source generator to create extensions for an enum type.
- Optimized for speed and low resource consumption
- Support for non-standard enum declarations
```csharp
public enum EPublicFoo : byte
```
- .NET 8+ support by using [FrozenDictionary](https://learn.microsoft.com/en-us/dotnet/api/system.collections.frozen.frozendictionary-2) & [FrozenSet](https://learn.microsoft.com/en-us/dotnet/api/system.collections.frozen.frozenset-1)
- .NET 5+ support by using [IReadOnlyDictionary](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ireadonlydictionary-2) & [IReadOnlySet](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ireadonlyset-1)
- .NET Framework 4.5+ support by using [IReadOnlyDictionary](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ireadonlydictionary-2) & [HashSet](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.hashset-1)**Package** - [FusionReactor.SourceGenerators.EnumExtensions](https://www.nuget.org/packages/FusionReactor.SourceGenerators.EnumExtensions/)
Add the package to your application using
```bash
dotnet add package FusionReactor.SourceGenerators.EnumExtensions
```Adding the package will automatically add a marker attribute, `[GenerateEnumExtensions]`, to your project.
To use the generator, add the `[GenerateEnumExtensions]` attribute to an enum. For example:
```csharp
[GenerateEnumExtensions]
[Description("Test 123")]
[IntArray(new[] { 123 })]
[StringArray(new[] { "Foo", "Bar", "Baz" })]
public enum EPublicFoo
{
[Display(
ShortName = "Fo",
Name = "Foo - 0",
Description = "Zero",
Prompt = "ooF",
GroupName = "Foos",
Order = 0)]
Foo = 0,[Display(
ShortName = "Ba",
Name = "Bar - 1",
Description = "One",
Prompt = "raB",
GroupName = "Bars",
Order = 1)]
Bar = 1,Batz = 2,
}```
This will generate a class called `EPublicFooExtensions` (`EPublicFoo` + `Extensions`), which contains a number of helper methods.
`EPublicFoo.Extensions.g.cs`:
```csharp
///
/// Extension methods for the enum.
///
[GeneratedCode("FusionReactor.SourceGenerators.EnumExtensions", null)]
public static class EPublicFooExtensions
{
#if NET8_0_OR_GREATER
private static readonly FrozenDictionary content
= new Dictionary
{
{ EPublicFoo.Foo, 0 },
{ EPublicFoo.Bar, 1 },
{ EPublicFoo.Batz, 2 },
}
.ToFrozenDictionary();
#else
private static readonly Dictionary contentDictionary
= new Dictionary
{
{ EPublicFoo.Foo, 0 },
{ EPublicFoo.Bar, 1 },
{ EPublicFoo.Batz, 2 },
};
private static readonly IReadOnlyDictionary content
= new ReadOnlyDictionary(contentDictionary);
#endif#if NET8_0_OR_GREATER
private static readonly FrozenSet names
= new HashSet()
{
"Foo",
"Bar",
"Batz",
}
.ToFrozenSet();
#elif NET5_0_OR_GREATER
private static readonly IReadOnlySet names
= new HashSet()
{
"Foo",
"Bar",
"Batz",
};
#else
private static readonly HashSet names
= new HashSet()
{
"Foo",
"Bar",
"Batz",
};
#endif#if NET8_0_OR_GREATER
private static readonly FrozenSet values
= new HashSet()
{
EPublicFoo.Foo,
EPublicFoo.Bar,
EPublicFoo.Batz,
}
.ToFrozenSet();
#elif NET5_0_OR_GREATER
private static readonly IReadOnlySet names
= new HashSet()
{
EPublicFoo.Foo,
EPublicFoo.Bar,
EPublicFoo.Batz,
};
#else
private static readonly HashSet names
= new HashSet()
{
EPublicFoo.Foo,
EPublicFoo.Bar,
EPublicFoo.Batz,
};
#endif#if NET8_0_OR_GREATER
private static readonly FrozenSet rootAttributes
= new HashSet()
{
new global::FusionReactor.SourceGenerators.EnumExtensions.GenerateEnumExtensionsAttribute(),
new global::System.ComponentModel.DescriptionAttribute(
"Test 123"),
new global::FusionReactor.SourceGenerators.EnumExtensions.Tests.Attributes.IntArrayAttribute(
new int[]{ 123 }),
new global::FusionReactor.SourceGenerators.EnumExtensions.Tests.Attributes.StringArrayAttribute(
new string[]{ "Foo", "Bar", "Baz" }),
}
.ToFrozenSet();
#elif NET5_0_OR_GREATER
private static readonly IReadOnlySet rootAttributes
= new HashSet()
{
new global::FusionReactor.SourceGenerators.EnumExtensions.GenerateEnumExtensionsAttribute(),
new global::System.ComponentModel.DescriptionAttribute(
"Test 123"),
new global::FusionReactor.SourceGenerators.EnumExtensions.Tests.Attributes.IntArrayAttribute(
new int[]{ 123 }),
new global::FusionReactor.SourceGenerators.EnumExtensions.Tests.Attributes.StringArrayAttribute(
new string[]{ "Foo", "Bar", "Baz" }),
};
#else
private static readonly HashSet rootAttributes
= new HashSet()
{
new global::FusionReactor.SourceGenerators.EnumExtensions.GenerateEnumExtensionsAttribute(),
new global::System.ComponentModel.DescriptionAttribute(
"Test 123"),
new global::FusionReactor.SourceGenerators.EnumExtensions.Tests.Attributes.IntArrayAttribute(
new int[]{ 123 }),
new global::FusionReactor.SourceGenerators.EnumExtensions.Tests.Attributes.StringArrayAttribute(
new string[]{ "Foo", "Bar", "Baz" }),
};
#endif#if NET8_0_OR_GREATER
private static readonly FrozenDictionary memberAttributes
= new Dictionary()
{
{
EPublicFoo.Foo,
new Attribute[1]
{
new global::System.ComponentModel.DataAnnotations.DisplayAttribute()
{
ShortName = "Fo",
Name = "Foo - 0",
Description = "Zero",
Prompt = "ooF",
GroupName = "Foos",
Order = 0,
},
}
},
{
EPublicFoo.Bar,
new Attribute[1]
{
new global::System.ComponentModel.DataAnnotations.DisplayAttribute()
{
ShortName = "Ba",
Name = "Bar - 1",
Description = "One",
Prompt = "raB",
GroupName = "Bars",
Order = 1,
},
}
},
{
EPublicFoo.Batz,
new Attribute[0]
},
}
.ToFrozenDictionary();
#else
private static readonly Dictionary memberAttributesDictionary
= new Dictionary()
{
{
EPublicFoo.Foo,
new Attribute[1]
{
new global::System.ComponentModel.DataAnnotations.DisplayAttribute()
{
ShortName = "Fo",
Name = "Foo - 0",
Description = "Zero",
Prompt = "ooF",
GroupName = "Foos",
Order = 0,
},
}
},
{
EPublicFoo.Bar,
new Attribute[1]
{
new global::System.ComponentModel.DataAnnotations.DisplayAttribute()
{
ShortName = "Ba",
Name = "Bar - 1",
Description = "One",
Prompt = "raB",
GroupName = "Bars",
Order = 1,
},
}
},
{
EPublicFoo.Batz,
new Attribute[0]
},
};
private static readonly IReadOnlyDictionary memberAttributes
= new ReadOnlyDictionary(memberAttributesDictionary);
#endif///
/// Gets the content dictionary containing mappings of enum values to values.
///
/// The read-only content dictionary.
#if NET8_0_OR_GREATER
public static FrozenDictionary GetContent()
#else
public static IReadOnlyDictionary GetContent()
#endif
=> content;
///
/// Gets the content dictionary containing mappings of enum values to values.
///
/// The enum value for which to get the content dictionary.
/// The read-only content dictionary.
#if NET8_0_OR_GREATER
public static FrozenDictionary GetContent(this EPublicFoo enumValue)
#else
public static IReadOnlyDictionary GetContent(this EPublicFoo enumValue)
#endif
=> content;///
/// Retrieves the name of the constant in the .
///
/// The enum value to convert.
///
/// A string containing the name of the ;
/// or if no such constant is found.
///
public static string? GetName(this EPublicFoo enumValue)
=> enumValue switch
{
EPublicFoo.Foo => nameof(EPublicFoo.Foo),
EPublicFoo.Bar => nameof(EPublicFoo.Bar),
EPublicFoo.Batz => nameof(EPublicFoo.Batz),
_ => null,
};
///
/// Retrieves all available names of the .
///
/// An enumerable collection of names.
#if NET8_0_OR_GREATER
public static FrozenSet GetNames()
#elif NET5_0_OR_GREATER
public static IReadOnlySet GetNames()
#else
public static HashSet GetNames()
#endif
=> names;
///
/// Retrieves all available names of the .
///
/// The enumeration value.
/// An enumerable collection of names.
#if NET8_0_OR_GREATER
public static FrozenSet GetNames(this EPublicFoo enumValue)
#elif NET5_0_OR_GREATER
public static IReadOnlySet GetNames(this EPublicFoo enumValue)
#else
public static HashSet GetNames(this EPublicFoo enumValue)
#endif
=> names;///
/// Retrieves all available values of the .
///
/// An enumerable collection of values.
#if NET8_0_OR_GREATER
public static FrozenSet GetValues()
#elif NET5_0_OR_GREATER
public static IReadOnlySet GetValues()
#else
public static HashSet GetValues()
#endif
=> values;
///
/// Retrieves all available values of the .
///
/// The enumeration value.
/// An enumerable collection of values.
#if NET8_0_OR_GREATER
public static FrozenSet GetValues(this EPublicFoo enumValue)
#elif NET5_0_OR_GREATER
public static IReadOnlySet GetValues(this EPublicFoo enumValue)
#else
public static HashSet GetValues(this EPublicFoo enumValue)
#endif
=> values;///
/// Parses the specified string representation of the enumeration value to its corresponding
/// value.
///
/// A string containing the name or value to convert.
///
/// A boolean indicating whether to ignore case during the parsing. Default is false.
///
///
/// The value equivalent to the specified string representation.
///
public static EPublicFoo ParseFast(string value, bool ignoreCase = false)
{
if (ignoreCase)
{
return value.ToLowerInvariant() switch
{
"foo" => EPublicFoo.Foo,
"bar" => EPublicFoo.Bar,
"batz" => EPublicFoo.Batz,
_ => throw new ArgumentException(),
};
}
else
{
return value switch
{
"Foo" => EPublicFoo.Foo,
"Bar" => EPublicFoo.Bar,
"Batz" => EPublicFoo.Batz,
_ => throw new ArgumentException(),
};
}
}
///
/// Parses the specified string representation of the enumeration value to its corresponding
/// value.
///
/// The enumeration value.
/// A string containing the name or value to convert.
///
/// A boolean indicating whether to ignore case during the parsing. Default is false.
///
///
/// The value equivalent to the specified string representation.
///
public static EPublicFoo ParseFast(this EPublicFoo enumValue, string value, bool ignoreCase = false)
{
if (ignoreCase)
{
return value.ToLowerInvariant() switch
{
"foo" => EPublicFoo.Foo,
"bar" => EPublicFoo.Bar,
"batz" => EPublicFoo.Batz,
_ => throw new ArgumentException(),
};
}
else
{
return value switch
{
"Foo" => EPublicFoo.Foo,
"Bar" => EPublicFoo.Bar,
"Batz" => EPublicFoo.Batz,
_ => throw new ArgumentException(),
};
}
}///
/// Tries to parse the specified string representation of an enumeration value to its corresponding
/// enumeration value.
///
/// The string representation of the enumeration value.
///
/// When this method returns, contains the value equivalent
/// to the string representation, if the parse succeeded, or default(EPublicFoo) if the parse failed.
/// true if the parsing was successful; otherwise, false.
public static bool TryParseFast(string value, out EPublicFoo? result)
=> TryParseFast(value, false, out result);
///
/// Tries to parse the specified string representation of an enumeration value to its corresponding
/// enumeration value.
///
/// The value to parse.
///
/// A boolean indicating whether to ignore case during the parsing. Default is false.
///
///
/// When this method returns, contains the value equivalent
/// to the string representation, if the parse succeeded, or null if the parse failed.
///
/// true if the parsing was successful; otherwise, false.
public static bool TryParseFast(string value, bool ignoreCase, out EPublicFoo? result)
{
if (ignoreCase)
{
result = value.ToLowerInvariant() switch
{
"foo" => EPublicFoo.Foo,
"bar" => EPublicFoo.Bar,
"batz" => EPublicFoo.Batz,
_ => null,
};
}
else
{
result = value switch
{
"Foo" => EPublicFoo.Foo,
"Bar" => EPublicFoo.Bar,
"Batz" => EPublicFoo.Batz,
_ => null,
};
}
return result is not null;
}
///
/// Tries to parse the specified string representation of an enumeration value to its corresponding
/// enumeration value.
///
/// The enumeration value.
/// The value to parse.
///
/// When this method returns, contains the value equivalent
/// to the string representation, if the parse succeeded, or null if the parse failed.
///
/// true if the parsing was successful; otherwise, false.
public static bool TryParseFast(this EPublicFoo enumValue, string value, out EPublicFoo? result)
=> enumValue.TryParseFast(value, false, out result);
///
/// Tries to parse the specified string representation of an enumeration value to its corresponding
/// enumeration value.
///
/// The enumeration value.
/// The value to parse.
///
/// A boolean indicating whether to ignore case during the parsing. Default is false.
///
///
/// When this method returns, contains the value equivalent
/// to the string representation, if the parse succeeded, or null if the parse failed.
///
/// true if the parsing was successful; otherwise, false.
public static bool TryParseFast(this EPublicFoo enumValue, string value, bool ignoreCase, out EPublicFoo? result)
{
if (ignoreCase)
{
result = value.ToLowerInvariant() switch
{
"foo" => EPublicFoo.Foo,
"bar" => EPublicFoo.Bar,
"batz" => EPublicFoo.Batz,
_ => null,
};
}
else
{
result = value switch
{
"Foo" => EPublicFoo.Foo,
"Bar" => EPublicFoo.Bar,
"Batz" => EPublicFoo.Batz,
_ => null,
};
}
return result is not null;
}///
/// Retrieves all available attributes of the .
///
/// An enumerable collection of attributes.
#if NET8_0_OR_GREATER
public static FrozenSet GetRootAttributes()
#elif NET5_0_OR_GREATER
public static IReadOnlySet GetRootAttributes()
#else
public static HashSet GetRootAttributes()
#endif
=> rootAttributes;
///
/// Retrieves all available attributes of the .
///
/// The enumeration value.
/// An enumerable collection of attributes.
#if NET8_0_OR_GREATER
public static FrozenSet GetRootAttributes(this EPublicFoo enumValue)
#elif NET5_0_OR_GREATER
public static IReadOnlySet GetRootAttributes(this EPublicFoo enumValue)
#else
public static HashSet GetRootAttributes(this EPublicFoo enumValue)
#endif
=> rootAttributes;///
/// Retrieves all available attributes of the .
///
/// An enumerable collection of attributes.
#if NET8_0_OR_GREATER
public static FrozenDictionary GetMemberAttributes()
#else
public static Dictionary GetMemberAttributes()
#endif
=> memberAttributes;
///
/// Retrieves all available attributes of the .
///
/// The enumeration value.
/// An enumerable collection of attributes.
#if NET8_0_OR_GREATER
public static FrozenDictionary GetMemberAttributes(this EPublicFoo enumValue)
#else
public static Dictionary GetMemberAttributes(this EPublicFoo enumValue)
#endif
=> memberAttributes;
}```
The generated extension files are available in your IDE under the Source Generators files.
## Contributing
Create an [issue](https://github.com/OhFlowi/FusionReactor.SourceGenerators.EnumExtensions/issues/new) if you find a BUG or have a Suggestion or Question. If you want to develop this project :
1. Fork it!
2. Create your feature branch: `git checkout -b my-new-feature`
3. Commit your changes: `git commit -am 'Add some feature'`
4. Push to the branch: `git push origin my-new-feature`
5. Submit a pull request## License
FusionReactor.SourceGenerators.EnumExtensions is Copyright © 2024 [OhFlowi](https://github.com/OhFlowi) under the MIT License.