github.com/sandwich-go/boost@v1.3.29/misc/annotation/registry.go (about) 1 package annotation 2 3 import ( 4 "fmt" 5 "github.com/sandwich-go/boost/xstrings" 6 "strconv" 7 "strings" 8 ) 9 10 const all = "*" 11 12 type resolver struct { 13 opts *Options 14 } 15 16 // New 创建一个解析器,默认使用 annotation@ 作为 MagicPrefix,只有包含 MagicPrefix 的行,才能萃取到注释 17 // descriptors 可以指定萃取的注释名,以及是否为合法的注释 18 // 若不指定 descriptors,则任意名的注释,均为合法的注释 19 func New(opts ...Option) Resolver { 20 v := &resolver{opts: NewOptions(opts...)} 21 if len(v.opts.GetDescriptors()) == 0 { 22 v.opts.ApplyOption(WithDescriptors(Descriptor{Name: all})) 23 } 24 return v 25 } 26 27 var EmptyAnnotation = &annotation{} 28 29 type annotation struct { 30 name string 31 line string 32 attributes map[string]string 33 } 34 35 func NewAnnotation(name string, attributes map[string]string) Annotation { 36 return &annotation{name: name, attributes: attributes} 37 } 38 39 func (a annotation) Name() string { return a.name } 40 func (a annotation) Line() string { return a.line } 41 func (a annotation) Contains(key string) bool { 42 _, ok := a.attributes[key] 43 return ok 44 } 45 46 func (a annotation) String(key string, defaultVal ...string) string { 47 v, ok := a.attributes[key] 48 if !ok { 49 return append(defaultVal, "")[0] 50 } 51 return xstrings.Trim(v) 52 } 53 54 func (a annotation) Int8(key string, defaultVal ...int8) (int8, error) { 55 val := a.String(key) 56 if len(val) == 0 { 57 return append(defaultVal, 0)[0], nil 58 } 59 iVal, err := strconv.ParseInt(val, 10, 8) 60 if err != nil { 61 return 0, err 62 } 63 return int8(iVal), nil 64 } 65 66 func (a annotation) Int16(key string, defaultVal ...int16) (int16, error) { 67 val := a.String(key) 68 if len(val) == 0 { 69 return append(defaultVal, 0)[0], nil 70 } 71 iVal, err := strconv.ParseInt(val, 10, 16) 72 if err != nil { 73 return 0, err 74 } 75 return int16(iVal), nil 76 } 77 78 func (a annotation) Int32(key string, defaultVal ...int32) (int32, error) { 79 val := a.String(key) 80 if len(val) == 0 { 81 return append(defaultVal, 0)[0], nil 82 } 83 iVal, err := strconv.ParseInt(val, 10, 32) 84 if err != nil { 85 return 0, err 86 } 87 return int32(iVal), nil 88 } 89 90 func (a annotation) Int64(key string, defaultVal ...int64) (int64, error) { 91 val := a.String(key) 92 if len(val) == 0 { 93 return append(defaultVal, 0)[0], nil 94 } 95 return strconv.ParseInt(val, 10, 64) 96 } 97 98 func (a annotation) Uint8(key string, defaultVal ...uint8) (uint8, error) { 99 val := a.String(key) 100 if len(val) == 0 { 101 return append(defaultVal, 0)[0], nil 102 } 103 iVal, err := strconv.ParseUint(val, 10, 8) 104 if err != nil { 105 return 0, err 106 } 107 return uint8(iVal), nil 108 } 109 110 func (a annotation) Uint16(key string, defaultVal ...uint16) (uint16, error) { 111 val := a.String(key) 112 if len(val) == 0 { 113 return append(defaultVal, 0)[0], nil 114 } 115 iVal, err := strconv.ParseUint(val, 10, 16) 116 if err != nil { 117 return 0, err 118 } 119 return uint16(iVal), nil 120 } 121 122 func (a annotation) Uint32(key string, defaultVal ...uint32) (uint32, error) { 123 val := a.String(key) 124 if len(val) == 0 { 125 return append(defaultVal, 0)[0], nil 126 } 127 iVal, err := strconv.ParseUint(val, 10, 32) 128 if err != nil { 129 return 0, err 130 } 131 return uint32(iVal), nil 132 } 133 134 func (a annotation) Uint64(key string, defaultVal ...uint64) (uint64, error) { 135 val := a.String(key) 136 if len(val) == 0 { 137 return append(defaultVal, 0)[0], nil 138 } 139 return strconv.ParseUint(val, 10, 64) 140 } 141 142 func (a annotation) Int(key string, defaultVal ...int) (int, error) { 143 val := a.String(key) 144 if len(val) == 0 { 145 return append(defaultVal, 0)[0], nil 146 } 147 iVal, err := strconv.ParseInt(val, 10, 32) 148 if err != nil { 149 return 0, err 150 } 151 return int(iVal), nil 152 } 153 154 func (a annotation) Float32(key string, defaultVal ...float32) (float32, error) { 155 val := a.String(key) 156 if len(val) == 0 { 157 return append(defaultVal, 0)[0], nil 158 } 159 iVal, err := strconv.ParseFloat(val, 32) 160 if err != nil { 161 return 0, err 162 } 163 return float32(iVal), nil 164 } 165 166 func (a annotation) Float64(key string, defaultVal ...float64) (float64, error) { 167 val := a.String(key) 168 if len(val) == 0 { 169 return append(defaultVal, 0)[0], nil 170 } 171 return strconv.ParseFloat(val, 64) 172 } 173 174 func (a annotation) Bool(key string, defaultVal ...bool) (bool, error) { 175 val := a.String(key) 176 if len(val) == 0 { 177 return append(defaultVal, false)[0], nil 178 } 179 return xstrings.IsTrue(xstrings.Trim(strings.ToLower(val))), nil 180 } 181 182 func (desc Descriptor) match(ann Annotation) bool { 183 if desc.Name != all && ann.Name() != desc.Name { 184 return false 185 } 186 if desc.Validator != nil { 187 return desc.Validator(ann) 188 } 189 return true 190 } 191 192 func (r *resolver) Resolve(line string) (Annotation, error) { 193 line = strings.TrimSpace(line) 194 for _, desc := range r.opts.GetDescriptors() { 195 if !strings.Contains(line, r.opts.GetMagicPrefix()) { 196 continue 197 } 198 ann, err := parser(line, r.opts.GetLowerKey()) 199 if err != nil { 200 return nil, err 201 } 202 if !desc.match(ann) { 203 continue 204 } 205 return ann, nil 206 } 207 return nil, ErrNoAnnotation 208 } 209 210 func (r *resolver) ResolveMany(lines ...string) ([]Annotation, error) { 211 as := make([]Annotation, 0, len(lines)) 212 for _, line := range lines { 213 if ann, err := r.Resolve(line); err == nil { 214 as = append(as, ann) 215 } else if err != ErrNoAnnotation { 216 return nil, err 217 } 218 } 219 return as, nil 220 } 221 222 func (r *resolver) ResolveWithName(name string, lines ...string) (Annotation, error) { 223 for _, line := range lines { 224 if ann, err := r.Resolve(line); err == nil && ann.Name() == name { 225 return ann, nil 226 } else if err != nil && err != ErrNoAnnotation { 227 return nil, err 228 } 229 } 230 return nil, ErrNoAnnotation 231 } 232 233 func (r *resolver) ResolveNoDuplicate(lines ...string) ([]Annotation, error) { 234 as, err := r.ResolveMany(lines...) 235 if err != nil || len(as) <= 1 { 236 return as, err 237 } 238 mapping := make(map[string]Annotation) 239 for _, v := range as { 240 if v1, ok := mapping[v.Name()]; ok { 241 return nil, fmt.Errorf("got duplicate annotation name with name: %s line1: %s line2: %s", v.Name(), v.Line(), v1.Line()) 242 } 243 mapping[v.Name()] = v 244 } 245 return as, nil 246 }