github.com/mailru/activerecord@v1.12.2/internal/pkg/parser/utils.go (about) 1 package parser 2 3 import ( 4 "go/ast" 5 "regexp" 6 "strings" 7 8 "github.com/mailru/activerecord/internal/pkg/arerror" 9 "golang.org/x/text/cases" 10 "golang.org/x/text/language" 11 ) 12 13 var PublicNameChecker = regexp.MustCompile("^[A-Z]") 14 var ToLower = cases.Lower(language.English) 15 var availableNodeName = []StructNameType{ 16 FieldsObject, 17 Fields, 18 ProcFields, 19 Indexes, 20 IndexParts, 21 Serializers, 22 Triggers, 23 Flags, 24 Mutators, 25 } 26 27 func getNodeName(node string) (name string, publicName string, packageName string, err error) { 28 for _, nName := range availableNodeName { 29 if strings.HasPrefix(node, string(nName)) { 30 name = string(nName) 31 publicName = node[len(nName):] 32 33 break 34 } 35 } 36 37 if publicName == "" { 38 err = arerror.ErrParseNodeNameUnknown 39 return 40 } 41 42 if !PublicNameChecker.MatchString(publicName) { 43 err = arerror.ErrParseNodeNameInvalid 44 return 45 } 46 47 packageName = ToLower.String(publicName) 48 49 return 50 } 51 52 const ( 53 NoCheckFlag = 0 54 CheckFlagEmpty = 1 << iota 55 ) 56 57 type ParamValueRule int 58 59 const ( 60 ParamNeedValue ParamValueRule = iota 61 ParamNotNeedValue 62 ) 63 64 const NameDefaultRule = "__DEFAULT__" 65 66 func splitTag(field *ast.Field, checkFlag uint32, rule map[TagNameType]ParamValueRule) ([][]string, error) { 67 if field.Tag == nil { 68 return nil, arerror.ErrParseTagSplitAbsent 69 } 70 71 if !strings.HasPrefix(field.Tag.Value, "`ar:\"") { 72 return nil, arerror.ErrParseTagInvalidFormat 73 } 74 75 if checkFlag&CheckFlagEmpty != 0 && field.Tag.Value == "`ar:\"\"`" { 76 return nil, arerror.ErrParseTagSplitEmpty 77 } 78 79 return splitParam(field.Tag.Value[4:len(field.Tag.Value)-1], rule) 80 } 81 82 func splitParam(str string, rule map[TagNameType]ParamValueRule) ([][]string, error) { 83 if _, ex := rule[NameDefaultRule]; !ex { 84 rule[NameDefaultRule] = ParamNeedValue 85 } 86 87 ret := [][]string{} 88 89 for _, param := range strings.Split(strings.Trim(str, "\""), ";") { 90 if param != "" { 91 kv := strings.SplitN(param, ":", 2) 92 93 r, ok := rule[TagNameType(kv[0])] 94 if !ok { 95 r = rule[NameDefaultRule] 96 } 97 98 if r == ParamNotNeedValue && len(kv) == 2 { 99 return nil, &arerror.ErrParseTagDecl{Name: kv[0], Err: arerror.ErrParseTagWithValue} 100 } 101 102 ret = append(ret, kv) 103 } 104 } 105 106 return ret, nil 107 } 108 109 func checkBoolType(indType ast.Expr) error { 110 switch t := indType.(type) { 111 case *ast.Ident: 112 if t.String() != string(TypeBool) { 113 return arerror.ErrTypeNotBool 114 } 115 default: 116 return arerror.ErrTypeNotBool 117 } 118 119 return nil 120 }