Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OpenAPI 3.1.0 enumeration style #121

Open
theimmigrant-canada opened this issue Oct 23, 2023 · 5 comments
Open

Add OpenAPI 3.1.0 enumeration style #121

theimmigrant-canada opened this issue Oct 23, 2023 · 5 comments
Labels
bug Something isn't working enhancement New feature or request future plans Maybe it will be in the very distant future.

Comments

@theimmigrant-canada
Copy link

theimmigrant-canada commented Oct 23, 2023

In OpenAPI 3.1.0 there is a new method of enumerating things that allows us to have proper names for enumerations.
Here is an example of that.

properties:
  LogLevel:
    type: integer
    oneOf:
      - title: Trace
        const: 0
        description: "A trace log level"
      - title: Debug
        const: 1
        description: "A debug log level"
      - title: Information
        const: 2
        description: "A information log level"

The main page of the project says that it supports OpenAPI 3.1 but this part still doesn't seem to be supported.
Here is a thread on the subject

@Carapacik Carapacik added bug Something isn't working enhancement New feature or request labels Oct 24, 2023
@tfrancois
Copy link

Let's fix this please. What will it take for it to be supported properly by Swagger (UI) and the like?

@JohnGalt1717
Copy link

JohnGalt1717 commented Oct 26, 2023

Or even x-ms-enum format which gives you the value that should be used, the name and description all of which can be used to generate an extended enum in Dart too. I.e. this

      "ArticleCategories": {
        "enum": [
          "Politics",
          "Sports",
          "Entertainment",
          "Finance",
          "Technology",
          "Travel",
          "Health",
          "Religion",
          "Science",
          "Education",
          "Environmental",
          "Lifestyle"
        ],
        "type": "string",
        "oneOf": [
          {
            "const": 1,
            "title": "Politics",
            "description": "Politics"
          },
          {
            "const": 2,
            "title": "Sports",
            "description": "Sports"
          },
          {
            "const": 4,
            "title": "Entertainment",
            "description": "Entertainment"
          },
          {
            "const": 8,
            "title": "Finance",
            "description": "Finance"
          },
          {
            "const": 16,
            "title": "Technology",
            "description": "Technology"
          },
          {
            "const": 32,
            "title": "Travel",
            "description": "Travel"
          },
          {
            "const": 64,
            "title": "Health",
            "description": "Health"
          },
          {
            "const": 128,
            "title": "Religion",
            "description": "Religion"
          },
          {
            "const": 256,
            "title": "Science",
            "description": "Science"
          },
          {
            "const": 512,
            "title": "Education",
            "description": "Education"
          },
          {
            "const": 1024,
            "title": "Environmental",
            "description": "Environmental"
          },
          {
            "const": 2048,
            "title": "Lifestyle",
            "description": "Lifestyle"
          }
        ]
      },

Should be able to generate this:

enum ArticleCategories {
  politics(1),
  sports(2),
  entertainment(4),
  finance(8),
  technology(16),
  travel(32),
  health(64),
  religion(128),
  science(256),
  education(512),
  environmental(1024),
  lifestyle(2048);

  const ArticleCategories(this.value);
  final int value;

  @override
  String toString() {
    switch (this) {
      case ArticleCategories.politics:
        return "Politics";
      case ArticleCategories.sports:
        return "Sports";
      case ArticleCategories.entertainment:
        return "Entertainment";
      case ArticleCategories.finance:
        return "Finance";
      case ArticleCategories.technology:
        return "Technology";
      case ArticleCategories.travel:
        return "Travel";
      case ArticleCategories.health:
        return "Health";
      case ArticleCategories.religion:
        return "Religion";
      case ArticleCategories.science:
        return "Science";
      case ArticleCategories.education:
        return "Education";
      case ArticleCategories.environmental:
        return "Environmental";
      case ArticleCategories.lifestyle:
        return "Lifestyle";
      default:
        throw UnimplementedError();
    }
  }
}

And of course it should be able to go further and have a get description accessor too.

@JohnGalt1717
Copy link

JohnGalt1717 commented Oct 26, 2023

Update, I have code that does this properly. It requires that the property have the enum array to be able to determine that it is indeed an enum.

If you'd like I can do a pull request and you can hack it up to meet your needs. This is what it produces (I don't have long descriptions only the name repeated):

// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint

import 'package:json_annotation/json_annotation.dart';

@JsonEnum()
enum ArticleCategories {
  /// Politics
  @JsonValue('1')
  politics('1'),

  /// Sports
  @JsonValue('2')
  sports('2'),

  /// Entertainment
  @JsonValue('4')
  entertainment('4'),

  /// Finance
  @JsonValue('8')
  finance('8'),

  /// Technology
  @JsonValue('16')
  technology('16'),

  /// Travel
  @JsonValue('32')
  travel('32'),

  /// Health
  @JsonValue('64')
  health('64'),

  /// Religion
  @JsonValue('128')
  religion('128'),

  /// Science
  @JsonValue('256')
  science('256'),

  /// Education
  @JsonValue('512')
  education('512'),

  /// Environmental
  @JsonValue('1024')
  environmental('1024'),

  /// Lifestyle
  @JsonValue('2048')
  lifestyle('2048');

  const ArticleCategories(this.json);

  final String? json;

  String? toJson() => json;

  @override
  String toString() {
    switch(this) {
        case ArticleCategories.politics:
          return "Politics";
        case ArticleCategories.sports:
          return "Sports";
        case ArticleCategories.entertainment:
          return "Entertainment";
        case ArticleCategories.finance:
          return "Finance";
        case ArticleCategories.technology:
          return "Technology";
        case ArticleCategories.travel:
          return "Travel";
        case ArticleCategories.health:
          return "Health";
        case ArticleCategories.religion:
          return "Religion";
        case ArticleCategories.science:
          return "Science";
        case ArticleCategories.education:
          return "Education";
        case ArticleCategories.environmental:
          return "Environmental";
        case ArticleCategories.lifestyle:
          return "Lifestyle";
    }
  }
  

  String toDescription() {
    switch(this) {
        case ArticleCategories.politics:
          return "Politics";
        case ArticleCategories.sports:
          return "Sports";
        case ArticleCategories.entertainment:
          return "Entertainment";
        case ArticleCategories.finance:
          return "Finance";
        case ArticleCategories.technology:
          return "Technology";
        case ArticleCategories.travel:
          return "Travel";
        case ArticleCategories.health:
          return "Health";
        case ArticleCategories.religion:
          return "Religion";
        case ArticleCategories.science:
          return "Science";
        case ArticleCategories.education:
          return "Education";
        case ArticleCategories.environmental:
          return "Environmental";
        case ArticleCategories.lifestyle:
          return "Lifestyle";
    }
  }
  
}

@JohnGalt1717
Copy link

JohnGalt1717 commented Feb 21, 2024

Bump: This is still broken and the enums it creates are "valueXXX" instead of proper names despite the fact that these are indeed available in the schema. It also doesn't properly override toString to return the proper values per the docs on new enums. It also doesn't set the name/value properly per new Dart enums so that it can have a numerical value associated with each item.

I'm specifically using dart_mappable, but any of them should generate similar to the above with a proper value and then simple name and then also be mappable to the value not the name for json.

JohnGalt1717 added a commit to JohnGalt1717/swagger_parser that referenced this issue Mar 25, 2024
Handles all cases of proper advanced enums with name/value if available. If not, defaults back to original structure.

May also fix Enum as part parameter Carapacik#207
JohnGalt1717 added a commit to JohnGalt1717/swagger_parser that referenced this issue Mar 25, 2024
@Carapacik Carapacik added the future plans Maybe it will be in the very distant future. label May 9, 2024
@JohnGalt1717
Copy link

I gave up on my pull request, but this is still a major blocker to this working correctly as it's basically impossible to use enums right now because you don't know which one is what.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request future plans Maybe it will be in the very distant future.
Projects
None yet
Development

No branches or pull requests

4 participants