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