Skip to content

Commit 925df37

Browse files
committed
feat: support get filed value
Change-Id: I450040c01436fc42143a3cca88348be082f60ab1
1 parent b80b3a3 commit 925df37

File tree

4 files changed

+137
-55
lines changed

4 files changed

+137
-55
lines changed

README.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,13 @@ Operator priority(high -> low):
154154
* `&&`
155155
* `||`
156156

157-
## Selector
157+
## Field Selector
158+
159+
```
160+
field_lv1.field_lv2...field_lvn
161+
```
162+
163+
## Expression Selector
158164

159165
If expression is **multiple model** and exprName is not `@`:
160166

expr_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ func TestExpr(t *testing.T) {
126126
if f, ok := c.val.(float64); ok && math.IsNaN(f) && math.IsNaN(val.(float64)) {
127127
continue
128128
}
129-
t.Fatalf("expr: %q, got: %v, want: %v", c.expr, val, c.val)
129+
t.Fatalf("expr: %q, got: %v, expect: %v", c.expr, val, c.val)
130130
}
131131
}
132132
}
@@ -154,7 +154,7 @@ func TestPriority(t *testing.T) {
154154
if f, ok := c.val.(float64); ok && math.IsNaN(f) && math.IsNaN(val.(float64)) {
155155
continue
156156
}
157-
t.Fatalf("expr: %q, got: %v, want: %v", c.expr, val, c.val)
157+
t.Fatalf("expr: %q, got: %v, expect: %v", c.expr, val, c.val)
158158
}
159159
}
160160
}
@@ -190,7 +190,7 @@ func TestBuiltInFunc(t *testing.T) {
190190
if f, ok := c.val.(float64); ok && math.IsNaN(f) && math.IsNaN(val.(float64)) {
191191
continue
192192
}
193-
t.Fatalf("expr: %q, got: %v, want: %v", c.expr, val, c.val)
193+
t.Fatalf("expr: %q, got: %v, expect: %v", c.expr, val, c.val)
194194
}
195195
}
196196
}
@@ -212,7 +212,7 @@ func TestSyntaxIncorrect(t *testing.T) {
212212
for _, c := range cases {
213213
_, err := parseExpr(c.incorrectExpr)
214214
if err == nil {
215-
t.Fatalf("want syntax incorrect: %s", c.incorrectExpr)
215+
t.Fatalf("expect syntax incorrect: %s", c.incorrectExpr)
216216
} else {
217217
t.Log(err)
218218
}

tagexpr.go

+52-43
Original file line numberDiff line numberDiff line change
@@ -27,31 +27,31 @@ import (
2727
// VM struct tag expression interpreter
2828
type VM struct {
2929
tagName string
30-
structJar map[string]*Struct
30+
structJar map[string]*structVM
3131
rw sync.RWMutex
3232
}
3333

34-
// Struct tag expression set of struct
35-
type Struct struct {
34+
// structVM tag expression set of struct
35+
type structVM struct {
3636
vm *VM
3737
name string
38-
fields map[string]*Field
38+
fields map[string]*fieldVM
3939
exprs map[string]*Expr
4040
selectorList []string
4141
}
4242

43-
// Field tag expression set of struct field
44-
type Field struct {
43+
// fieldVM tag expression set of struct field
44+
type fieldVM struct {
4545
reflect.StructField
46-
host *Struct
46+
host *structVM
4747
valueGetter func(uintptr) interface{}
4848
}
4949

5050
// New creates a tag expression interpreter that uses @tagName as the tag name.
5151
func New(tagName string) *VM {
5252
return &VM{
5353
tagName: tagName,
54-
structJar: make(map[string]*Struct, 256),
54+
structJar: make(map[string]*structVM, 256),
5555
}
5656
}
5757

@@ -109,7 +109,7 @@ func (vm *VM) Run(structPtr interface{}) (*TagExpr, error) {
109109
return s.newTagExpr(v.Pointer()), nil
110110
}
111111

112-
func (vm *VM) registerStructLocked(structType reflect.Type) (*Struct, error) {
112+
func (vm *VM) registerStructLocked(structType reflect.Type) (*structVM, error) {
113113
structType, err := vm.getStructType(structType)
114114
if err != nil {
115115
return nil, err
@@ -119,14 +119,14 @@ func (vm *VM) registerStructLocked(structType reflect.Type) (*Struct, error) {
119119
if had {
120120
return s, nil
121121
}
122-
s = vm.newStruct()
122+
s = vm.newStructVM()
123123
vm.structJar[structTypeName] = s
124124
var numField = structType.NumField()
125125
var structField reflect.StructField
126-
var sub *Struct
126+
var sub *structVM
127127
for i := 0; i < numField; i++ {
128128
structField = structType.Field(i)
129-
field, err := s.newField(structField)
129+
field, err := s.newFieldVM(structField)
130130
if err != nil {
131131
return nil, err
132132
}
@@ -160,17 +160,17 @@ func (vm *VM) registerStructLocked(structType reflect.Type) (*Struct, error) {
160160
return s, nil
161161
}
162162

163-
func (vm *VM) newStruct() *Struct {
164-
return &Struct{
163+
func (vm *VM) newStructVM() *structVM {
164+
return &structVM{
165165
vm: vm,
166-
fields: make(map[string]*Field, 16),
166+
fields: make(map[string]*fieldVM, 16),
167167
exprs: make(map[string]*Expr, 64),
168168
selectorList: make([]string, 0, 64),
169169
}
170170
}
171171

172-
func (s *Struct) newField(structField reflect.StructField) (*Field, error) {
173-
f := &Field{
172+
func (s *structVM) newFieldVM(structField reflect.StructField) (*fieldVM, error) {
173+
f := &fieldVM{
174174
StructField: structField,
175175
host: s,
176176
}
@@ -182,15 +182,15 @@ func (s *Struct) newField(structField reflect.StructField) (*Field, error) {
182182
return f, nil
183183
}
184184

185-
func (f *Field) newFrom(ptr uintptr, ptrDeep int) reflect.Value {
185+
func (f *fieldVM) newFrom(ptr uintptr, ptrDeep int) reflect.Value {
186186
v := reflect.NewAt(f.Type, unsafe.Pointer(ptr+f.Offset)).Elem()
187187
for i := 0; i < ptrDeep; i++ {
188188
v = v.Elem()
189189
}
190190
return v
191191
}
192192

193-
func (f *Field) setFloatGetter(kind reflect.Kind, ptrDeep int) {
193+
func (f *fieldVM) setFloatGetter(kind reflect.Kind, ptrDeep int) {
194194
if ptrDeep == 0 {
195195
f.valueGetter = func(ptr uintptr) interface{} {
196196
return getFloat64(kind, ptr+f.Offset)
@@ -206,7 +206,7 @@ func (f *Field) setFloatGetter(kind reflect.Kind, ptrDeep int) {
206206
}
207207
}
208208

209-
func (f *Field) setBoolGetter(ptrDeep int) {
209+
func (f *fieldVM) setBoolGetter(ptrDeep int) {
210210
if ptrDeep == 0 {
211211
f.valueGetter = func(ptr uintptr) interface{} {
212212
return *(*bool)(unsafe.Pointer(ptr + f.Offset))
@@ -222,7 +222,7 @@ func (f *Field) setBoolGetter(ptrDeep int) {
222222
}
223223
}
224224

225-
func (f *Field) setStringGetter(ptrDeep int) {
225+
func (f *fieldVM) setStringGetter(ptrDeep int) {
226226
if ptrDeep == 0 {
227227
f.valueGetter = func(ptr uintptr) interface{} {
228228
return *(*string)(unsafe.Pointer(ptr + f.Offset))
@@ -238,13 +238,13 @@ func (f *Field) setStringGetter(ptrDeep int) {
238238
}
239239
}
240240

241-
func (f *Field) setLengthGetter(ptrDeep int) {
241+
func (f *fieldVM) setLengthGetter(ptrDeep int) {
242242
f.valueGetter = func(ptr uintptr) interface{} {
243243
return f.newFrom(ptr, ptrDeep).Interface()
244244
}
245245
}
246246

247-
func (f *Field) parseExprs(tag string) error {
247+
func (f *fieldVM) parseExprs(tag string) error {
248248
raw := tag
249249
tag = strings.TrimSpace(tag)
250250
if tag == "" {
@@ -300,11 +300,11 @@ func (f *Field) parseExprs(tag string) error {
300300
}
301301
}
302302

303-
func (s *Struct) copySubFields(field *Field, sub *Struct, ptrDeep int) {
303+
func (s *structVM) copySubFields(field *fieldVM, sub *structVM, ptrDeep int) {
304304
nameSpace := field.Name
305305
for k, v := range sub.fields {
306306
valueGetter := v.valueGetter
307-
f := &Field{
307+
f := &fieldVM{
308308
StructField: v.StructField,
309309
host: v.host,
310310
}
@@ -315,11 +315,11 @@ func (s *Struct) copySubFields(field *Field, sub *Struct, ptrDeep int) {
315315
}
316316
} else {
317317
f.valueGetter = func(ptr uintptr) interface{} {
318-
newField := reflect.NewAt(field.Type, unsafe.Pointer(ptr+field.Offset))
318+
newFieldVM := reflect.NewAt(field.Type, unsafe.Pointer(ptr+field.Offset))
319319
for i := 0; i < ptrDeep; i++ {
320-
newField = newField.Elem()
320+
newFieldVM = newFieldVM.Elem()
321321
}
322-
return valueGetter(uintptr(newField.Pointer()))
322+
return valueGetter(uintptr(newFieldVM.Pointer()))
323323
}
324324
}
325325
}
@@ -344,7 +344,7 @@ func (vm *VM) getStructType(t reflect.Type) (reflect.Type, error) {
344344
return structType, nil
345345
}
346346

347-
func (s *Struct) newTagExpr(ptr uintptr) *TagExpr {
347+
func (s *structVM) newTagExpr(ptr uintptr) *TagExpr {
348348
te := &TagExpr{
349349
s: s,
350350
ptr: ptr,
@@ -354,60 +354,69 @@ func (s *Struct) newTagExpr(ptr uintptr) *TagExpr {
354354

355355
// TagExpr struct tag expression evaluator
356356
type TagExpr struct {
357-
s *Struct
357+
s *structVM
358358
ptr uintptr
359359
}
360360

361361
// EvalFloat evaluate the value of the struct tag expression by the selector expression.
362362
// NOTE:
363363
// If the expression value type is not float64, return 0.
364-
func (t *TagExpr) EvalFloat(selector string) float64 {
365-
r, _ := t.Eval(selector).(float64)
364+
func (t *TagExpr) EvalFloat(exprSelector string) float64 {
365+
r, _ := t.Eval(exprSelector).(float64)
366366
return r
367367
}
368368

369369
// EvalString evaluate the value of the struct tag expression by the selector expression.
370370
// NOTE:
371371
// If the expression value type is not string, return "".
372-
func (t *TagExpr) EvalString(selector string) string {
373-
r, _ := t.Eval(selector).(string)
372+
func (t *TagExpr) EvalString(exprSelector string) string {
373+
r, _ := t.Eval(exprSelector).(string)
374374
return r
375375
}
376376

377377
// EvalBool evaluate the value of the struct tag expression by the selector expression.
378378
// NOTE:
379379
// If the expression value type is not bool, return false.
380-
func (t *TagExpr) EvalBool(selector string) bool {
381-
r, _ := t.Eval(selector).(bool)
380+
func (t *TagExpr) EvalBool(exprSelector string) bool {
381+
r, _ := t.Eval(exprSelector).(bool)
382382
return r
383383
}
384384

385385
// Eval evaluate the value of the struct tag expression by the selector expression.
386386
// NOTE:
387387
// format: fieldName, fieldName.exprName, fieldName1.fieldName2.exprName1
388388
// result types: float64, string, bool, nil
389-
func (t *TagExpr) Eval(selector string) interface{} {
390-
expr, ok := t.s.exprs[selector]
389+
func (t *TagExpr) Eval(exprSelector string) interface{} {
390+
expr, ok := t.s.exprs[exprSelector]
391391
if !ok {
392392
return nil
393393
}
394-
return expr.run(getFieldSelector(selector), t)
394+
return expr.run(getFieldSelector(exprSelector), t)
395395
}
396396

397397
// Range loop through each tag expression
398398
// NOTE:
399399
// eval result types: float64, string, bool, nil
400-
func (t *TagExpr) Range(fn func(selector string, eval func() interface{}) bool) {
400+
func (t *TagExpr) Range(fn func(exprSelector string, eval func() interface{}) bool) {
401401
exprs := t.s.exprs
402-
for _, selector := range t.s.selectorList {
403-
if !fn(selector, func() interface{} {
404-
return exprs[selector].run(getFieldSelector(selector), t)
402+
for _, exprSelector := range t.s.selectorList {
403+
if !fn(exprSelector, func() interface{} {
404+
return exprs[exprSelector].run(getFieldSelector(exprSelector), t)
405405
}) {
406406
return
407407
}
408408
}
409409
}
410410

411+
// Field returns the field reflect.Value specified by the selector.
412+
func (t *TagExpr) Field(fieldSelector string) reflect.Value {
413+
f, ok := t.s.fields[fieldSelector]
414+
if !ok {
415+
return reflect.Value{}
416+
}
417+
return reflect.NewAt(f.Type, unsafe.Pointer(t.ptr+f.Offset)).Elem()
418+
}
419+
411420
func (t *TagExpr) getValue(field string, subFields []interface{}) (v interface{}) {
412421
f, ok := t.s.fields[field]
413422
if !ok {

0 commit comments

Comments
 (0)