Openapi-generator: [BUG][R] Generating R enums results in empty class with no values

Created on 15 Jul 2019  路  12Comments  路  Source: OpenAPITools/openapi-generator

Description

I have noticed that R enums are not generated properly, that is, instead of a proper enum structure, an empty class is generated. In it, there is nothing but the to-/fromJSON-methods; the values of the enum - that are specified in the schema - are not present.

openapi-generator version

openapi generator 4.0.1 (gradle plugin)

OpenAPI declaration file content or url

generated with json Schema:

{
  "openapi": "3.0.0",
  "info": {
    "title": "JSON test",
    "version": "1.0.0-SNAPSHOT"
  },
  "paths": {
  },
  "components": {
    "schemas": {
      "EnumTest": {
        "enum": [
          "One",
          "Two",
          "Three"
        ],
        "type": "string"
      }
    }
  }
}
Command line used for generation

task generate_R_test(type: org.openapitools.generator.gradle.plugin.tasks.GenerateTask) {
inputSpec = "$rootDir/src/schema/new/test.schema.json".toString()
outputDir = "$rootDir/src/data/r_model/test".toString()
generatorName = 'r'

systemProperties = [
    models: "", // generate only models, but all of them
]

}

Steps to reproduce
  1. use the gradle plugin with the above command to generate the enum
  2. open the enum file (enum_test.R)
  3. see that it generates an empty class without any of the enum values
Related issues/PRs

I have seearched for this issue but not found a similar case for R (only for Javascript, see https://github.com/swagger-api/swagger-codegen/issues/4819, but I do not know how helpful that will be)

Suggest a fix

I am not really familiar with the whole code, but upon looking at the code, I think the problem is that model.moustache is also used to generate enums. Because the values are described differently in the Schema, they might not be recognised properly

R Enum Bug

All 12 comments

馃憤 Thanks for opening this issue!
馃彿 I have applied any labels matching special text in your issue.

The team will review the labels and make any necessary changes.

@Leo-Rutschmann given the example you provided, what does the enum class look like in R?

@wing328 the generated enum class looks as follows:

# JSON test
#
# No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
#
# The version of the OpenAPI document: 1.0.0-SNAPSHOT
# 
# Generated by: https://openapi-generator.tech


#' EnumTest Class
#'
#'
#' @importFrom R6 R6Class
#' @importFrom jsonlite fromJSON toJSON
#' @export
EnumTest <- R6::R6Class(
  'EnumTest',
  public = list(
    initialize = function(, ...){
      local.optional.var <- list(...)
    },
    toJSON = function() {
      EnumTestObject <- list()

      EnumTestObject
    },
    fromJSON = function(EnumTestJson) {
      EnumTestObject <- jsonlite::fromJSON(EnumTestJson)
    },
    toJSONString = function() {
      sprintf(
        '{
        }',
      )
    },
    fromJSONString = function(EnumTestJson) {
      EnumTestObject <- jsonlite::fromJSON(EnumTestJson)
      self
    }
  )
)`

As you can see, all the values are ignored, sicne the mustache-template does not consider enum values.

In the meantime I have found a workaround by copying the model.mustache and by modifying it so it uses the {{#isEnum}} and {{#enumVars}} tags where needed; I compared with the java Generator templates, which have a separate model for enums (or two, to be exact, there also is modelInnerEnum.mustache): modeEnum.mustache
For this to work I added a new directory template, placed my template there, and appended templateDir = "$rootDir/src/schema/new/template".toString() to my gradle command, which now works fine; the issue thus really is that the current template ignores enums, I think.

@Leo-Rutschmann you're totally correct. The R client generator does not support enum model/class yet.

As you've already figured out how other generators support enum class, I believe you're heading the right direction.

I wonder if you can file a PR with the fix so that we can include it in the official project.

@wing328 I have found out that it did not work smoothly, and I am still working on fixing everything - the generator struggles with R data types and I have not found a way to correctly convert to and from JSON for every type, and those that work as of now only work because of a ton of ifs & the like.
I also used a small plugin for the enums, and the template looks terribly messy as it is right now (appart from being unfinished).
Thus I am afraid but I don't think that I can file a PR with a solution any time soon; I would like to, but I don't see myself finding the time to get a clean solution in the near future - maybe around January, but certainly not before that.
Sorry for not being able to help more

@Leo-Rutschmann that's perfectly fine. Let's see if anyone else from the community can help out on this.

Hi @Leo-Rutschmann
If you have some example that I can work with, I can look into this enum translation.
I'm working with an API that has this yml configuration:

v1_ComparisonFilterOperator:
      description: 'Comparison operators allowed in matrix filters.'
      type: string
      enum:
        - '='
        - '!='
        - '>'
        - '<'
        - '>='
        - '<='
        - 'in'

I have the corresponding R operations vector as c("==", "!=", ">", "<", ">=", "<=", "%in%").
I want to figure out a way to make it compatible.

Your help is appreciated.

Best,
Marcel

Hi William, @wing328, Leo @Leo-Rutschmann
I would still like to work on auto-generating an enum-like structure in R.聽
I saw this post on SO that might help:聽https://stackoverflow.com/questions/33838392/enum-like-arguments-in-r
If I can get a minimal example for testing. I can give it a go.聽

Hi Marcel @LiNk-NY, sorry for not replying - I am busy at university right now (which is why I don't find time to fix the issue until january). Unfortunately I cannot send you any examples of my work on this because I have done all of it at a summer job and I don't have any access to those files. Thus I'll try to give you a description of what I did:
In my quick fix version, I added a new template for enums (see the description of my workaround in my reply from July 18th). There are still other problems in the template which may corrupt the data somewhat when converting back and forth; these can be fixed, however, by:

  • tidying up to- and fromJsonString in the template (it should really just call to- or fromJson and then stringify the response)
  • set simplifyVector, simplifyDataframe and simplifyMatrix to false (very important, this makes things a lot easier!) when using R's fromJson-method. This prevents R from messing with arrays which was a big problem for me.

I hope this helps you in some way.

Update: I started working on an modelEnum.mustache file and made modifications to the existing model.mustache. See it at https://github.com/LiNk-NY/openapi-generator/tree/enum
I'm still working on making changes to the API file.
@Leo-Rutschmann

Update: I don't have an example API template with 'enum's in it.
Perhaps this can be added to the petstore API?

See the comparison here:
https://github.com/OpenAPITools/openapi-generator/compare/master...LiNk-NY:enum

Hi all, @Leo-Rutschmann @wing328
Thank you for your help.
Please see the current PR #5728.
-Marcel

Was this page helpful?
0 / 5 - 0 ratings