OpenAPITools / OpenAPITools/openapi-generator

[REQ] Could an option be added to the C# generator to support Enums as string where the values are actually bit flags.

Open
#17,121 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Enhancement: Feature
Dominant language
Java
Stars
26.8k
Forks
7.7k
PR merge metrics
PR metrics pending

Description

Is your feature request related to a problem? Please describe.

I can't satisfactorily support enums that represent bit flags in sdks generated by openapi-generator

Describe the solution you'd like

I don't know whether this has been requested before so apologies if it has and I didn't spot it.

I wondered if it would be possible to support enums as string where the values represent bit flags.

In my API there are some properties which are enums which are decorated with the [Flags] annotation. For example:

[Flags]
public enum Weather
{
    Sun = 1,
    Rain = 2,
    Wind = 4,
    Lightning = 8
}

In my Startup.cs I have:

        services.AddControllers()
            .AddJsonOptions(opt =>
            {
                opt.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
            }

This adds the following to the swagger spec.

  "Weather": {
      "enum": [
        "Sun",
        "Rain",
        "Wind",
        "Lightning"
      ],
      "type": "string"
    },

As per above, the swagger spec doesn't include any numeric values, so the generator can't know that this enum represents bit flags. In the openapi-generator generated code you get:

    public enum Weather
    {
        /// <summary>
        /// Enum Sun for value: Sun
        /// </summary>
        [EnumMember(Value = "Sun")]
        Sun = 1,

        /// <summary>
        /// Enum Rain for value: Rain
        /// </summary>
        [EnumMember(Value = "Rain")]
        Rain = 2,

        /// <summary>
        /// Enum Wind for value: Wind
        /// </summary>
        [EnumMember(Value = "Wind")]
        Wind = 3

        /// <summary>
        /// Enum Lightning for value: Lightning
        /// </summary>
        [EnumMember(Value = "Lightning")]
        Lightning = 4
    }

The API accepts multiple enum values in the input and JsonStringEnumConverter will convert values from/to the correct combination of flags during serialization/deserialization. For example:

"weatherToday": "Sun,Wind,Lightning"

This would arrive in my controller as:

Sun | Wind | Lightning = 13

It would be nice if the cli supported an option, for example, --flag-enums "<comma separated list of all enums which represent bit flags>", and apply special logic for this set of enums:

  • The auto-generated enum would be assigned the [Flags] annotation.
  • Bit flag numbers 1, 2, 4, 8, 16, 32, etc would be assigned to each value (NB. for this to work they would not need to match those used in the API which is good since the swagger spec doesn't include them), allowing the client code to build up combinations of flags.

So in my example above the auto-generated code would become:

    [Flags]
    public enum Weather
    {
        /// <summary>
        /// Enum Sun for value: Sun
        /// </summary>
        [EnumMember(Value = "Sun")]
        Sun = 1 << 0,

        /// <summary>
        /// Enum Rain for value: Rain
        /// </summary>
        [EnumMember(Value = "Rain")]
        Rain = 1 << 1,

        /// <summary>
        /// Enum Wind for value: Wind
        /// </summary>
        [EnumMember(Value = "Wind")]
        Wind = 1 << 2,

        /// <summary>
        /// Enum Lightning for value: Lightning
        /// </summary>
        [EnumMember(Value = "Lightning")]
        Lightning = 1 << 4
    }

There is just one gotcha. This solution would not work where the enum in the API includes values which are built up from combinations of bit flags and/or where there is a value defined for 0 (ie None), but I'd argue that this is an acceptable limitation that should be clearly documented.

Describe alternatives you've considered

The workaround is to change the spec of my APIs to accept an array of flags, then bitwise OR them in my controller.

Additional context

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the C# generator and its CLI option/configuration entry points; the issue does not name specific files or tests. Compare existing enum generation behavior with the requested flag-enum handling, then define how selected enums receive [Flags] and power-of-two values while documenting the stated limitations.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
cli, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.