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  }