github.com/josephspurrier/go-swagger@v0.2.1-0.20221129144919-1f672a142a00/scan/enum.go (about) 1 //go:build !go1.11 2 // +build !go1.11 3 4 package scan 5 6 import ( 7 "go/ast" 8 "strconv" 9 "strings" 10 "unicode" 11 ) 12 13 func upperSnakeCase(s string) string { 14 in := []rune(s) 15 isLower := func(idx int) bool { 16 return idx >= 0 && idx < len(in) && unicode.IsLower(in[idx]) 17 } 18 19 out := make([]rune, 0, len(in)+len(in)/2) 20 21 for i, r := range in { 22 if unicode.IsUpper(r) { 23 r = unicode.ToLower(r) 24 if i > 0 && in[i-1] != '_' && (isLower(i-1) || isLower(i+1)) { 25 out = append(out, '_') 26 } 27 } 28 out = append(out, r) 29 } 30 31 return strings.ToUpper(string(out)) 32 } 33 34 func getEnumBasicLitValue(basicLit *ast.BasicLit) interface{} { 35 switch basicLit.Kind.String() { 36 case "INT": 37 if result, err := strconv.ParseInt(basicLit.Value, 10, 64); err == nil { 38 return result 39 } 40 case "FLOAT": 41 if result, err := strconv.ParseFloat(basicLit.Value, 64); err == nil { 42 return result 43 } 44 default: 45 return strings.Trim(basicLit.Value, "\"") 46 } 47 return nil 48 } 49 50 func getEnumValues(file *ast.File, typeName string) (list []interface{}) { 51 for _, decl := range file.Decls { 52 genDecl, ok := decl.(*ast.GenDecl) 53 54 if !ok { 55 continue 56 } 57 58 if genDecl.Tok.String() == "const" { 59 for _, spec := range genDecl.Specs { 60 if valueSpec, ok := spec.(*ast.ValueSpec); ok { 61 switch valueSpec.Type.(type) { 62 case *ast.Ident: 63 if valueSpec.Type.(*ast.Ident).Name == typeName { 64 if basicLit, ok := valueSpec.Values[0].(*ast.BasicLit); ok { 65 list = append(list, getEnumBasicLitValue(basicLit)) 66 } 67 } 68 default: 69 var name = valueSpec.Names[0].Name 70 if strings.HasPrefix(name, upperSnakeCase(typeName)) { 71 var values = strings.SplitN(name, "__", 2) 72 if len(values) == 2 { 73 list = append(list, values[1]) 74 } 75 } 76 } 77 78 } 79 80 } 81 } 82 } 83 return 84 }