Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/OhFlowi/FusionReactor.SourceGenerators.EnumExtensions


https://github.com/OhFlowi/FusionReactor.SourceGenerators.EnumExtensions

Last synced: about 1 month ago
JSON representation

Awesome Lists containing this project

README

        

[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://raw.githubusercontent.com/OhFlowi/FusionReactor.SourceGenerators.EnumExtensions/master/LICENSE)
[![Nuget](https://img.shields.io/nuget/dt/FusionReactor.SourceGenerators.EnumExtensions?label=Nuget.org%20Downloads&style=flat-square&color=blue)](https://www.nuget.org/packages/FusionReactor.SourceGenerators.EnumExtensions)
[![Nuget](https://img.shields.io/nuget/vpre/FusionReactor.SourceGenerators.EnumExtensions.svg?label=NuGet)](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]
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. The new class is splitted in two files (`EPublicFoo` + `Extensions.Base.g.cs` & `EPublicFoo` + `Extensions.DisplayAttribute.g.cs`)

`EPublicFooExtensions.Base.g.cs`:

```csharp
///
/// Extension methods for the enum.
///
[GeneratedCode("FusionReactor.SourceGenerators.EnumExtensions", null)]
public static partial 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 []
{
"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 []
{
EPublicFoo.Foo,
EPublicFoo.Bar,
EPublicFoo.Batz,
}
.ToFrozenSet();
#elif NET5_0_OR_GREATER
private static readonly IReadOnlySet values = new HashSet()
{
EPublicFoo.Foo,
EPublicFoo.Bar,
EPublicFoo.Batz,
};
#else
private static readonly HashSet values = new HashSet()
{
EPublicFoo.Foo,
EPublicFoo.Bar,
EPublicFoo.Batz,
};
#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
{
return 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
{
return 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)
{
return 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
{
return 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
{
return 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
{
return 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
{
return 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 current 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)
{
return TryParseFast(value, false, out result);
}

///
/// Tries to parse the specified string representation of an enumeration value to its corresponding
/// enumeration value.
///
/// The string representation of the enumeration value.
/// A boolean indicating whether case should be ignored when parsing.
///
/// 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, 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 != null;
}

///
/// Tries to parse the specified string representation of an enumeration value to its corresponding
/// enumeration value.
///
/// The enumeration value to parse.
/// 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(this EPublicFoo enumValue, string value, out EPublicFoo? result)
{
return TryParseFast(value, false, out result);
}

///
/// Tries to parse the specified string representation of an enumeration value to its corresponding
/// enumeration value.
///
/// The enumeration value to parse.
/// The string representation of the enumeration value.
/// A boolean indicating whether case should be ignored when parsing.
///
/// 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(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 != null;
}
}
```

`EPublicFooExtensions.DisplayAttribute.g.cs`:
```csharp
public static partial class EPublicFooExtensions
{
#if !NET8_0_OR_GREATER
private static readonly Dictionary displayResultsDictionary = new Dictionary
{
{
EPublicFoo.Foo,
new DisplayResult
{
ShortName = "Fo",
Name = "Foo - 0",
Description = "Zero",
Prompt = "ooF",
GroupName = "Foos",
Order = 0,
}
},
{
EPublicFoo.Bar,
new DisplayResult
{
ShortName = "Ba",
Name = "Bar - 1",
Description = "One",
Prompt = "raB",
GroupName = "Bars",
Order = 1,
}
},
{
EPublicFoo.Batz,
null
},
};
#endif
///
/// Returns the of the enum.
///
/// The display attribute result or the enum value.
#if NET8_0_OR_GREATER
public static FrozenDictionary DisplayResults => new Dictionary
{
{
EPublicFoo.Foo,
new DisplayResult
{
ShortName = "Fo",
Name = "Foo - 0",
Description = "Zero",
Prompt = "ooF",
GroupName = "Foos",
Order = 0,
}},
{
EPublicFoo.Bar,
new DisplayResult
{
ShortName = "Ba",
Name = "Bar - 1",
Description = "One",
Prompt = "raB",
GroupName = "Bars",
Order = 1,
}},
{
EPublicFoo.Batz,
null
},
}
.ToFrozenDictionary();
#else
public static IReadOnlyDictionary DisplayResults => new ReadOnlyDictionary(displayResultsDictionary);
#endif

///
/// Returns the of the enum.
///
/// The enum value.
/// The display name or the enum value.
public static string? DisplayShortName(this EPublicFoo enumValue)
{
return enumValue switch
{
EPublicFoo.Foo => "Fo",
EPublicFoo.Bar => "Ba",
EPublicFoo.Batz => null,
_ => null
};
}

///
/// Returns the of the enum.
///
/// The enum value.
/// The name or the enum value.
public static string? DisplayName(this EPublicFoo enumValue)
{
return enumValue switch
{
EPublicFoo.Foo => "Foo - 0",
EPublicFoo.Bar => "Bar - 1",
EPublicFoo.Batz => null,
_ => null
};
}

///
/// Returns the of the enum.
///
/// The enum value.
/// The display name or the enum value.
public static string? DisplayDescription(this EPublicFoo enumValue)
{
return enumValue switch
{
EPublicFoo.Foo => "Zero",
EPublicFoo.Bar => "One",
EPublicFoo.Batz => null,
_ => null
};
}

///
/// Returns the of the enum.
///
/// The enum value.
/// The display name or the enum value.
public static string? DisplayPrompt(this EPublicFoo enumValue)
{
return enumValue switch
{
EPublicFoo.Foo => "ooF",
EPublicFoo.Bar => "raB",
EPublicFoo.Batz => null,
_ => null
};
}

///
/// Returns the of the enum.
///
/// The enum value.
/// The display name or the enum value.
public static string? DisplayGroupName(this EPublicFoo enumValue)
{
return enumValue switch
{
EPublicFoo.Foo => "Foos",
EPublicFoo.Bar => "Bars",
EPublicFoo.Batz => null,
_ => null
};
}

///
/// Returns the of the enum.
///
/// The enum value.
/// The display name or the enum value.
public static int? DisplayOrder(this EPublicFoo enumValue)
{
return enumValue switch
{
EPublicFoo.Foo => 0,
EPublicFoo.Bar => 1,
EPublicFoo.Batz => null,
_ => null
};
}
}
```

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.