Code Monkey home page Code Monkey logo

enumutilities's Introduction

Enum Utilities

Build status OpenSSF Scorecard GitHub license Nuget Nuget

A source generator for C# that uses Roslyn to create extensions and parsers for enumerations

๐Ÿƒ Quickstart ย  | ย  ๐Ÿ“— Guide ย  | ย  ๐Ÿ“ฆ NuGet


A source generator for C# that uses Roslyn to create extensions and parsers for enumerations, allowing to get a value associated to enum member or parse back from attribute value to enum member. All code generated at compile time thus avoid using reflection or boilerplate code.

Compatibility

Raiqub.Generators.EnumUtilities runs with Roslyn compiler so does not introduce a new dependency to your project besides a library containing the EnumGenerator attribute.

It requires at least the .NET 6 SDK to run, but you can target earlier frameworks.

Quickstart

Add the package to your application using

dotnet add package Raiqub.Generators.EnumUtilities

Adding the package will automatically add a marker attribute, [EnumGenerator], to your project.

To use the generator, add the [EnumGenerator] attribute to an enum. For example:

[EnumGenerator]
public enum Categories
{
   Electronics,
   Food,
   Automotive,
   Arts,
   BeautyCare,
   Fashion
}

This will generate 3 classes with the following methods:

  • CategoriesExtensions
    • ToStringFast(this Categories)
    • IsDefined(this Categories)
    • InterlockedAdd(this ref Categories, int)
    • InterlockedDecrement(this ref Categories)
    • InterlockedIncrement(this ref Categories)
    • InterlockedCompareExchange(this ref Categories, Categories, Categories)
    • InterlockedExchange(this ref Categories, Categories)
  • CategoriesFactory
    • TryParse(string?, StringComparison, out Categories)
    • TryParseIgnoreCase(string?, out Categories)
    • TryParse(string?, out Categories)
    • TryParse(string?, StringComparison)
    • TryParseIgnoreCase(string?)
    • TryParse(string?)
    • GetValues()
    • GetNames()
  • CategoriesValidation
    • IsDefined(Categories)
    • IsDefined(string?, StringComparison)
    • IsDefinedIgnoreCase(string?)
    • IsDefined(string?)

Bit flags enums are supported too:

[Flags]
[EnumGenerator]
public enum Colours
{
    Red = 1,
    Blue = 2,
    Green = 4,
}

Then 3 classes will be generated with the following methods:

  • ColoursExtensions
    • ToStringFast(this Colours)
    • IsDefined(this Colours)
    • InterlockedAnd(this ref Colours, Colours)
    • InterlockedOr(this ref Colours, Colours)
    • InterlockedCompareExchange(this ref Colours, Colours, Colours)
    • InterlockedExchange(this ref Colours, Colours)
  • ColoursFactory
    • TryParse(string?, StringComparison, out Colours)
    • TryParse(string?, out Colours)
    • TryParseIgnoreCase(string?, out Colours)
    • TryParse(string?)
    • TryParseIgnoreCase(string?)
    • TryParse(string?, StringComparison)
    • GetValues()
    • GetNames()
  • ColoursValidation
    • IsDefined(Colours)
    • IsDefined(string?, StringComparison)
    • IsDefinedIgnoreCase(string?)
    • IsDefined(string?)

All generated code are properly nullable annotated and removed from code coverage.

Guide

The following attributes are supported:

Example:

[EnumGenerator]
public enum PaymentMethod
{
    [EnumMember(Value = "Credit card")]
    Credit,
    [EnumMember(Value = "Debit card")]
    Debit,
    Cash,
    Cheque
}

This will generate the following methods:

  • PaymentMethodExtensions
    • ToEnumMemberValue(this PaymentMethod)
  • PaymentMethodFactory
    • TryParseFromEnumMemberValue(string?, StringComparison, out PaymentMethod)
    • TryParseFromEnumMemberValue(string?, out PaymentMethod)
    • TryParseFromEnumMemberValue(string?, StringComparison)
    • TryParseFromEnumMemberValue(string?)

Example:

[EnumGenerator]
public enum PaymentMethod
{
    Credit,
    Debit,
    [Description("The payment by using physical cash")]
    Cash,
    Cheque
}

This will generate the following methods:

  • PaymentMethodExtensions
    • GetDescription(this PaymentMethod)
  • PaymentMethodFactory
    • TryCreateFromDescription(string?, StringComparison, out PaymentMethod)
    • TryCreateFromDescription(string?, out PaymentMethod)
    • TryCreateFromDescription(string?, StringComparison)
    • TryCreateFromDescription(string?)

Example:

[EnumGenerator]
public enum WeekDays
{
    [Display(
        Name = nameof(Strings.MondayFull),
        ShortName = nameof(Strings.MondayShort),
        Description = nameof(Strings.MondayDescription),
        ResourceType = typeof(Strings))]
    Monday,
    [Display(ShortName = "Tue")]
    Tuesday,
    [Display]
    Wednesday,
    [Display(Name = "Thursday")]
    Thursday,
    [Display(Name = "Friday", ShortName = "Fri")]
    Friday,
    [Display(ShortName = "Sat", Description = "Almost the last day of the week")]
    Saturday,
    [Display(Description = "The last day of the week")]
    Sunday
}

Note that if ResourceType is provided the generated code will correctly get the value from resource.

This will generate the following methods:

  • WeekDaysExtensions
    • GetDisplayShortName(this WeekDays)
    • GetDisplayName(this WeekDays)
    • GetDescription(this WeekDays)
  • WeekDaysFactory
    • TryCreateFromDisplayShortName(string?, StringComparison, out WeekDays)
    • TryCreateFromDisplayShortName(string?, out WeekDays)
    • TryCreateFromDisplayShortName(string?, StringComparison)
    • TryCreateFromDisplayShortName(string?)
    • TryCreateFromDisplayName(string?, StringComparison, out WeekDays)
    • TryCreateFromDisplayName(string?, out WeekDays)
    • TryCreateFromDisplayName(string?, StringComparison)
    • TryCreateFromDisplayName(string?)
    • TryCreateFromDescription(string?, StringComparison, out WeekDays)
    • TryCreateFromDescription(string?, out WeekDays)
    • TryCreateFromDescription(string?, StringComparison)
    • TryCreateFromDescription(string?)

JSON Serialization

Besides the member name, supports the EnumMemberAttribute and JsonPropertyNameAttribute attributes.

Example:

[JsonConverterGenerator]
[JsonConverter(typeof(SeasonJsonConverter))]
public enum Season
{
    [EnumMember(Value = "\ud83c\udf31")]
    Spring = 1,
    [EnumMember(Value = "\u2600\ufe0f")]
    Summer,
    [EnumMember(Value = "\ud83c\udf42")]
    Autumn,
    [EnumMember(Value = "\u26c4")]
    Winter
}

This will generate the following JSON converter: SeasonJsonConverter.

Contributing

If something is not working for you or if you think that the source file should change, feel free to create an issue or Pull Request. I will be happy to discuss and potentially integrate your ideas!

License

See the LICENSE file for details.

enumutilities's People

Contributors

dependabot[bot] avatar renovate[bot] avatar skarllot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

enumutilities's Issues

Exception when source is empty

Generator 'EnumUtilitiesGenerator' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type 'ArgumentOutOfRangeException' with message 'Index was out of range. Must be non-negative and less than or equal to the size of the collection. (Parameter 'chunkLength')'  System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than or equal to the size of the collection. (Parameter 'chunkLength') at System.Text.StringBuilder.ToString() at Raiqub.Generators.EnumUtilities.EnumUtilitiesGenerator.AddExtensionsSource(EnumToGenerate type, SourceProductionContext context) in C:\Users\skarl\source\repos\github\skarllot\EnumUtilities\src\EnumUtilities\EnumUtilitiesGenerator.Emitter.cs:line 68 at Raiqub.Generators.EnumUtilities.EnumUtilitiesGenerator.Emit(Compilation compilation, SourceProductionContext context, ImmutableArray`1 types) in C:\Users\skarl\source\repos\github\skarllot\EnumUtilities\src\EnumUtilities\EnumUtilitiesGenerator.Emitter.cs:line 42 at Microsoft.CodeAnalysis.UserFunctionExtensions.c__DisplayClass3_0`2. b__0(TInput1 input1, TInput2 input2, CancellationToken token) in Z:\BuildAgent\work\3b7ce003563d6f8f\src\Compilers\Core\Portable\SourceGeneration\UserFunction.cs:line 101

[Feature request]: Support flags enum for JsonConverter

Is your feature request related to a specific problem? Or an existing feature?

Ensure proper de/serialization support of flags enum

Describe the solution you'd like

Allocation free serialization and research whether should use commas or pipes

Additional context

No response

[Feature request]: Support Interlocked

Is your feature request related to a specific problem? Or an existing feature?

Support Interlocked methods like CompareExchange

Describe the solution you'd like

Extension methods

Additional context

No response

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

This repository currently has no open or pending branches.

Detected dependencies

github-actions
.github/workflows/codeql.yml
  • step-security/harden-runner v2.6.1@eb238b55efaa70779f274895e782ed17c84f2895
  • actions/checkout v4.1.1@b4ffde65f46336ab88eb53be808477a3936bae11
  • actions/setup-dotnet v4.0.0@4d6c8fcf3c8f7a60068d26b594648e99df24cee3
  • actions/cache v3.3.3@e12d46a63a90f2fae62d114769bbf2a179198b5c
  • github/codeql-action v3.23.0@e5f05b81d5b6ff8cfa111c80c22c5fd02a384118
  • github/codeql-action v3.23.0@e5f05b81d5b6ff8cfa111c80c22c5fd02a384118
.github/workflows/dependency-review.yml
  • step-security/harden-runner v2.6.1@eb238b55efaa70779f274895e782ed17c84f2895
  • actions/checkout v4.1.1@b4ffde65f46336ab88eb53be808477a3936bae11
  • actions/dependency-review-action v3.1.5@c74b580d73376b7750d3d2a50bfb8adc2c937507
.github/workflows/dotnet.yml
  • step-security/harden-runner v2.6.1@eb238b55efaa70779f274895e782ed17c84f2895
  • actions/checkout v4.1.1@b4ffde65f46336ab88eb53be808477a3936bae11
  • actions/setup-dotnet v4.0.0@4d6c8fcf3c8f7a60068d26b594648e99df24cee3
  • actions/cache v3.3.3@e12d46a63a90f2fae62d114769bbf2a179198b5c
  • codecov/codecov-action v3.1.4@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d
.github/workflows/package.yml
  • step-security/harden-runner v2.6.1@eb238b55efaa70779f274895e782ed17c84f2895
  • actions/checkout v4.1.1@b4ffde65f46336ab88eb53be808477a3936bae11
  • actions/setup-dotnet v4.0.0@4d6c8fcf3c8f7a60068d26b594648e99df24cee3
  • actions/cache v3.3.3@e12d46a63a90f2fae62d114769bbf2a179198b5c
.github/workflows/scorecard.yml
  • step-security/harden-runner v2.6.1@eb238b55efaa70779f274895e782ed17c84f2895
  • actions/checkout v4.1.1@b4ffde65f46336ab88eb53be808477a3936bae11
  • ossf/scorecard-action v2.3.1@0864cf19026789058feabb7e87baa5f140aac736
  • actions/upload-artifact v4.1.0@1eb3cb2b3e0f29609092a73eb033bb759a334595
  • github/codeql-action v3.23.0@e5f05b81d5b6ff8cfa111c80c22c5fd02a384118
nuget
Directory.Build.props
  • Nerdbank.GitVersioning 3.6.133
  • DotNet.ReproducibleBuilds 1.1.1
global.json
  • dotnet-sdk 8.0.101
src/EnumUtilities/EnumUtilities.csproj
  • Polyfill 2.0.1
  • Microsoft.CodeAnalysis.Analyzers 3.3.4

  • Check this box to trigger a request for Renovate to run again on this repository

Support generating ValueConverter

Support generating Microsoft.EntityFrameworkCore.Storage.ValueConversion.ValueConverter<> for enum.

[assembly: EnumValueConverterGenerator(typeof(MyEnum), DefaultValue = 0)]

[DevApe] Ready for Action ๐Ÿš€

Hi @skarllot! ๐Ÿ‘‹

dev-ape

Thank you for installing DevApe! ๐Ÿ‘จ๐Ÿฝโ€๐Ÿ’ป๐Ÿฆ I wanted to let you know I'm ready for use. Here's what I can do for you:

๐Ÿ”ง Create custom rules for your repository

  • Tag me (@DevApeAI) in a comment with your desired rules.
  • I will enforce these rules during pull request reviews.

๐Ÿšจ When a new Pull Request is created...

  • I automatically review it for code quality, security vulnerabilities, and compliance with your custom rules.

๐Ÿ“Š When a new Issue is created...

  • I provide AI-powered insights and suggestions to help resolve the issue faster.
  • I can also auto-label and prioritize issues based on their content and context.

๐Ÿ’ฌ Whenever you need assistance...

  • Tag me (@DevApeAI) in a comment anywhere in your repository.
  • I can answer questions about your codebase, provide code snippets, documentation links, and more!

If you have any questions or need support, feel free to reach out at [email protected].

Let's build amazing things together! ๐Ÿš€

Use GeneratedCodeAttribute

Use GeneratedCodeAttribute for generated methods.

Example:

[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "6.0.7.2304")]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.