oapi-codegen icon indicating copy to clipboard operation
oapi-codegen copied to clipboard

underscores are incorrectly removed in enums

Open david-chenevert-lr opened this issue 9 months ago • 1 comments

TLDR:

enum.SOME_ENUM_NAME becomes SOMMEENUMNAME ... which is not the spec.

INPUT:

openapi: 3.0.1
paths:
  '/someendpoint':
    get:
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SomeSchema'
components:
  parameters: {}
  schemas:
    SomeSchema:
      type: string
      enum:
        - SOME_ENUM_NAME

OUTPUT:

// Package oapi provides primitives to interact with the openapi HTTP API.
//
// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.4.1 DO NOT EDIT.
package oapi
      
// Defines values for SomeSchema.
const (   
  SOMEENUMNAME SomeSchema = "SOME_ENUM_NAME"
)             
                
// SomeSchema defines model for SomeSchema.
type SomeSchema string

david-chenevert-lr avatar Jun 01 '25 19:06 david-chenevert-lr

is this the bug?

  1. globally, nameNormalizer to chosen to be ToCamelCase, which removes underscores. https://github.com/oapi-codegen/oapi-codegen/blob/main/pkg/codegen/utils.go#L35

POSSIBLE BUGS? a. maybe this is the wrong conversion, for an enum item name b. maybe ToCamelCase should not remove underscores c. not really a bug, but the name ToCamelCase does not describe this code. In the code (and its comment), ABC_DEF does not become abcDef; it becomes all-capitals ABCDEF

  1. ToCamelCase is used in the functions like renameSChema
933:func renameSchema(schemaName string, schemaRef *openapi3.SchemaRef) (string, error) {
952:func renameParameter(parameterName string, parameterRef *openapi3.ParameterRef) (string, error) {
970:func renameResponse(responseName string, responseRef *openapi3.ResponseRef) (string, error) {
988:func renameRequestBody(requestBodyName string, requestBodyRef *openapi3.RequestBodyRef) (string, error) {

https://github.com/oapi-codegen/oapi-codegen/blob/main/pkg/codegen/utils.go#L929-L1002

which leads to:

  1. The comment for the ToCamelCase() function is:
// ToCamelCase will convert query-arg style strings to CamelCase. We will
// use `., -, +, :, ;, _, ~, ' ', (, ), {, }, [, ]` as valid delimiters for words.
// So, "word.word-word+word:word;word_word~word word(word)word{word}[word]"
// would be converted to WordWordWordWordWordWordWordWordWordWordWordWordWord

https://github.com/oapi-codegen/oapi-codegen/blob/main/pkg/codegen/utils.go#L220-L2233

BUG SYMPTOM An enum named "ABC_DEF" should not be renamed to "ABCDEF", it should remain "ABC_DEF". IMO, there could be three ore more functions:

a. ToCamelCase, which would turn "ABC_DEF #$@" into "abcDef" b. ToEnumCharset, which would turn "ABC_DEF #$@" into "ABC_DEF" c. ToStrictCharset, which would be the new name for ToCamelCase. it would still turn "ABC_DEF #$@" into "ABCDEF"

I don't know what the rules for Schema, Request, Response, and RequestBody are. Each of them would use the matching function above, or require a different "To...()" function.

Also, for Enum maybe there should be a new renameEnum() function.

  1. the body of the function implements the rule described in the comment:
func ToCamelCase(str string) string {    s := strings.Trim(str, " ")     n := ""
    capNext := true 
    for _, v := range s {
        if unicode.IsUpper(v) {
            n += string(v)
        }    
        if unicode.IsDigit(v) {
            n += string(v)
        }    
        if unicode.IsLower(v) {
            if capNext {
                n += strings.ToUpper(string(v))
            } else {
                n += string(v)
            }    
        }    
        _, capNext = separatorSet[v]
    }    
    return n
}

https://github.com/oapi-codegen/oapi-codegen/blob/main/pkg/codegen/utils.go#L224-L246

david-chenevert-lr avatar Jun 01 '25 19:06 david-chenevert-lr