Skip to content

Commit

Permalink
refactor: add out enum types
Browse files Browse the repository at this point in the history
  • Loading branch information
byashimov committed Mar 1, 2024
1 parent 2043ba8 commit 0b6b031
Show file tree
Hide file tree
Showing 27 changed files with 2,406 additions and 1,149 deletions.
25 changes: 7 additions & 18 deletions generator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"github.com/dave/jennifer/jen"
"github.com/iancoleman/strcase"
"github.com/kelseyhightower/envconfig"
"golang.org/x/exp/maps"
"gopkg.in/yaml.v3"
)

Expand Down Expand Up @@ -125,17 +124,14 @@ func exec() error {
continue
}

if param.Name == "version_id" {
param.Schema.Type = SchemaTypeInteger
}

param.Ref = ref.Ref
params = append(params, param)
}

if strings.HasSuffix(p.Path, versionIDParam) {
params = append(params, &Parameter{
Name: "version_id",
Schema: &Schema{Type: SchemaTypeInteger},
})
}

p.Parameters = params
}
}
Expand Down Expand Up @@ -346,13 +342,10 @@ func exec() error {
file.Add(structMeth.Block(block...))
}

scopeValues := maps.Values(scope)
sort.Slice(scopeValues, func(i, j int) bool {
return scopeValues[i].CamelName < scopeValues[j].CamelName
})

for _, v := range scopeValues {
for _, k := range sortedKeys(scope) {
v := scope[k]
err = writeStruct(file, v)

if err != nil {
return err
}
Expand Down Expand Up @@ -395,10 +388,6 @@ var reMakesSense = regexp.MustCompile(`\w`)

// nolint:funlen // It's a generator, it's supposed to be long, and we won't expand it.
func writeStruct(f *jen.File, s *Schema) error {
if s.isMap() || s.isArray() || s.isScalar() && !s.isEnum() {
return nil
}

// nolint:nestif // It's a generator, it's supposed to be long, and we won't expand it.
if s.isEnum() {
kind := getScalarType(s)
Expand Down
85 changes: 49 additions & 36 deletions generator/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package main
import (
"encoding/json"
"fmt"
"regexp"
"sort"
"strings"

Expand Down Expand Up @@ -143,7 +144,7 @@ type Schema struct {
in, out bool // Request or Response DTO
}

// nolint:funlen,gocognit // It is easy to maintain and read, we don't need to split it
// nolint:funlen,gocognit,gocyclo // It is easy to maintain and read, we don't need to split it
func (s *Schema) init(doc *Doc, scope map[string]*Schema, name string) {
if s.Ref != "" {
other, err := doc.getSchema(s.Ref)
Expand Down Expand Up @@ -175,13 +176,13 @@ func (s *Schema) init(doc *Doc, scope map[string]*Schema, name string) {
if s.isEnum() {
const enumTypeSuffix = "Type"

if !strings.HasSuffix(s.CamelName, enumTypeSuffix) {
s.CamelName += enumTypeSuffix
betterName := getEnumName(s)
if betterName != s.name {
s.CamelName = cleanEnumName.ReplaceAllString(strcase.ToCamel(betterName), "") + s.CamelName
}

// When it is just "Type" it is useless
if s.CamelName == enumTypeSuffix {
s.CamelName = s.parent.CamelName + s.CamelName
if !strings.Contains(s.CamelName, enumTypeSuffix) {
s.CamelName += enumTypeSuffix
}
}

Expand All @@ -194,6 +195,19 @@ func (s *Schema) init(doc *Doc, scope map[string]*Schema, name string) {
}
}

// Some cases just impossible to cover
switch s.CamelName {
case "MessageFormatVersionValueType":
s.CamelName = "MessageFormatVersionType"
case "ServiceKafkaConnectConnectorStatusStateType":
s.CamelName = "ServiceKafkaConnectConnectorStateType"
case "PeeringConnectionStateType", "VpcPeeringConnectionWithResourceGroupStateType",
"VpcPeeringConnectionWithRegionStateType":
s.CamelName = "VpcPeeringConnectionStateType"
case "ServiceSchemaRegistryGlobalConfigGetOut":
s.CamelName = "ServiceSchemaRegistryCompatibilityLevelType"
}

if s.isPrivate() {
s.CamelName = lowerFirst(s.CamelName)
}
Expand Down Expand Up @@ -226,39 +240,22 @@ func (s *Schema) init(doc *Doc, scope map[string]*Schema, name string) {
}
}

if s.isObject() {
keys := sortedKeys(scope)
outer:
for len(keys) > 0 {
for _, k := range keys {
other := scope[k]
if other.hash() == s.hash() {
continue
}

// A duplicate
if other.CamelName == s.CamelName {
s.CamelName += "Alt"

continue outer
}
if s.isObject() || s.isEnum() {
for s.parent != nil {
v, ok := scope[s.CamelName]
if !ok {
break
}

break outer
}

scope[s.hash()] = s
}
if v.hash() == s.hash() {
// This is a duplicate
return
}

if s.isEnum() {
// Enums compared by enum list
// In case if they are equal, they must have the same name
other, ok := scope[s.hash()]
if ok {
s.CamelName = other.CamelName
} else {
scope[s.hash()] = s
s.CamelName += "Alt"
}

scope[s.CamelName] = s
}
}

Expand Down Expand Up @@ -297,7 +294,7 @@ func (s *Schema) isMap() bool {
}

func (s *Schema) isEnum() bool {
return len(s.Enum) != 0 && s.isIn()
return len(s.Enum) != 0
}

func (s *Schema) root() *Schema {
Expand All @@ -308,10 +305,12 @@ func (s *Schema) root() *Schema {
return s.parent.root()
}

// isIn is request object
func (s *Schema) isIn() bool {
return s.root().in
}

// isOut is response object
func (s *Schema) isOut() bool {
return s.root().out
}
Expand Down Expand Up @@ -407,3 +406,17 @@ func sortedKeys[T any](m map[string]T) []string {

return keys
}

var cleanEnumName = regexp.MustCompile("(Create|Get|Update|Delete|Stop|Cancel|Verify|Put)")

// getEnumName enum can't have just "state" name, drills to the root until finds something
func getEnumName(s *Schema) string {
switch s.name {
case "type", "value", "state", "status":
if s.parent != nil {
return getEnumName(s.parent)
}
}

return s.name
}
Loading

0 comments on commit 0b6b031

Please sign in to comment.