Skip to content

Commit 7efa838

Browse files
committed
feat: Update *TagExpr.Range method and fix *Validator.Validate method
Change-Id: I96d0823e593c7f2878a93b2aaa5c7edda8e6de90
1 parent 91cae92 commit 7efa838

File tree

6 files changed

+202
-110
lines changed

6 files changed

+202
-110
lines changed

fieldhandler.go

Lines changed: 0 additions & 54 deletions
This file was deleted.

handler.go

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package tagexpr
2+
3+
import "reflect"
4+
5+
// FieldHandler field handler
6+
type FieldHandler struct {
7+
selector string
8+
field *fieldVM
9+
expr *TagExpr
10+
}
11+
12+
func newFieldHandler(expr *TagExpr, fieldSelector string, field *fieldVM) *FieldHandler {
13+
return &FieldHandler{
14+
selector: fieldSelector,
15+
field: field,
16+
expr: expr,
17+
}
18+
}
19+
20+
// StringSelector returns the field selector of string type.
21+
func (f *FieldHandler) StringSelector() string {
22+
return f.selector
23+
}
24+
25+
// FieldSelector returns the field selector of FieldSelector type.
26+
func (f *FieldHandler) FieldSelector() FieldSelector {
27+
return FieldSelector(f.selector)
28+
}
29+
30+
// Value returns the field value.
31+
// NOTE:
32+
// If initZero==true, initialize nil pointer to zero value
33+
func (f *FieldHandler) Value(initZero bool) reflect.Value {
34+
return f.field.reflectValueGetter(f.expr.ptr, initZero)
35+
}
36+
37+
// EvalFuncs returns the tag expression eval functions.
38+
func (f *FieldHandler) EvalFuncs() map[ExprSelector]func() interface{} {
39+
targetTagExpr, _ := f.expr.checkout(f.selector)
40+
evals := make(map[ExprSelector]func() interface{}, len(f.field.exprs))
41+
for k, v := range f.field.exprs {
42+
expr := v
43+
exprSelector := ExprSelector(k)
44+
evals[exprSelector] = func() interface{} {
45+
return expr.run(exprSelector.Name(), targetTagExpr)
46+
}
47+
}
48+
return evals
49+
}
50+
51+
// StructField returns the field StructField object.
52+
func (f *FieldHandler) StructField() reflect.StructField {
53+
return f.field.structField
54+
}
55+
56+
// ExprHandler expr handler
57+
type ExprHandler struct {
58+
base string
59+
path string
60+
selector string
61+
expr *TagExpr
62+
targetExpr *TagExpr
63+
}
64+
65+
func newExprHandler(te, tte *TagExpr, base, es string) *ExprHandler {
66+
return &ExprHandler{
67+
base: base,
68+
selector: es,
69+
expr: te,
70+
targetExpr: tte,
71+
}
72+
}
73+
74+
// TagExpr returns the *TagExpr.
75+
func (e *ExprHandler) TagExpr() *TagExpr {
76+
return e.expr
77+
}
78+
79+
// StringSelector returns the expression selector of string type.
80+
func (e *ExprHandler) StringSelector() string {
81+
return e.selector
82+
}
83+
84+
// ExprSelector returns the expression selector of ExprSelector type.
85+
func (e *ExprHandler) ExprSelector() ExprSelector {
86+
return ExprSelector(e.selector)
87+
}
88+
89+
// Path returns the path description of the expression.
90+
func (e *ExprHandler) Path() string {
91+
if e.path == "" {
92+
if e.targetExpr.path == "" {
93+
e.path = e.selector
94+
} else {
95+
e.path = e.targetExpr.path + FieldSeparator + e.selector
96+
}
97+
}
98+
return e.path
99+
}
100+
101+
// Eval evaluate the value of the struct tag expression.
102+
// NOTE:
103+
// result types: float64, string, bool, nil
104+
func (e *ExprHandler) Eval() interface{} {
105+
return e.expr.s.exprs[e.selector].run(e.base, e.targetExpr)
106+
}
107+
108+
// EvalFloat evaluates the value of the struct tag expression.
109+
// NOTE:
110+
// If the expression value type is not float64, return 0.
111+
func (e *ExprHandler) EvalFloat() float64 {
112+
r, _ := e.Eval().(float64)
113+
return r
114+
}
115+
116+
// EvalString evaluates the value of the struct tag expression.
117+
// NOTE:
118+
// If the expression value type is not string, return "".
119+
func (e *ExprHandler) EvalString() string {
120+
r, _ := e.Eval().(string)
121+
return r
122+
}
123+
124+
// EvalBool evaluates the value of the struct tag expression.
125+
// NOTE:
126+
// If the expression value is not 0, '' or nil, return true.
127+
func (e *ExprHandler) EvalBool() bool {
128+
return FakeBool(e.Eval())
129+
}

tagexpr.go

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -659,23 +659,23 @@ type TagExpr struct {
659659
path string
660660
}
661661

662-
// EvalFloat evaluate the value of the struct tag expression by the selector expression.
662+
// EvalFloat evaluates the value of the struct tag expression by the selector expression.
663663
// NOTE:
664664
// If the expression value type is not float64, return 0.
665665
func (t *TagExpr) EvalFloat(exprSelector string) float64 {
666666
r, _ := t.Eval(exprSelector).(float64)
667667
return r
668668
}
669669

670-
// EvalString evaluate the value of the struct tag expression by the selector expression.
670+
// EvalString evaluates the value of the struct tag expression by the selector expression.
671671
// NOTE:
672672
// If the expression value type is not string, return "".
673673
func (t *TagExpr) EvalString(exprSelector string) string {
674674
r, _ := t.Eval(exprSelector).(string)
675675
return r
676676
}
677677

678-
// EvalBool evaluate the value of the struct tag expression by the selector expression.
678+
// EvalBool evaluates the value of the struct tag expression by the selector expression.
679679
// NOTE:
680680
// If the expression value is not 0, '' or nil, return true.
681681
func (t *TagExpr) EvalBool(exprSelector string) bool {
@@ -721,7 +721,7 @@ func (t *TagExpr) RangeFields(fn func(*FieldHandler) bool) bool {
721721
return true
722722
}
723723

724-
// Eval evaluate the value of the struct tag expression by the selector expression.
724+
// Eval evaluates the value of the struct tag expression by the selector expression.
725725
// NOTE:
726726
// format: fieldName, fieldName.exprName, fieldName1.fieldName2.exprName1
727727
// result types: float64, string, bool, nil
@@ -752,25 +752,16 @@ func (t *TagExpr) Eval(exprSelector string) interface{} {
752752
// When fn returns false, interrupt traversal and return false.
753753
// NOTE:
754754
// eval result types: float64, string, bool, nil
755-
func (t *TagExpr) Range(fn func(path string, es ExprSelector, eval func() interface{}) error) error {
755+
func (t *TagExpr) Range(fn func(*ExprHandler) error) error {
756756
var err error
757757
if list := t.s.exprSelectorList; len(list) > 0 {
758-
exprs := t.s.exprs
759758
for _, es := range list {
760759
dir, base := splitFieldSelector(es)
761760
targetTagExpr, err := t.checkout(dir)
762761
if err != nil {
763762
continue
764763
}
765-
var path string
766-
if targetTagExpr.path == "" {
767-
path = es
768-
} else {
769-
path = targetTagExpr.path + FieldSeparator + es
770-
}
771-
err = fn(path, ExprSelector(es), func() interface{} {
772-
return exprs[es].run(base, targetTagExpr)
773-
})
764+
err = fn(newExprHandler(t, targetTagExpr, base, es))
774765
if err != nil {
775766
return err
776767
}
@@ -866,7 +857,7 @@ func (t *TagExpr) Range(fn func(path string, es ExprSelector, eval func() interf
866857
return nil
867858
}
868859

869-
func (t *TagExpr) subRange(omitNil bool, path string, value reflect.Value, fn func(string, ExprSelector, func() interface{}) error) error {
860+
func (t *TagExpr) subRange(omitNil bool, path string, value reflect.Value, fn func(*ExprHandler) error) error {
870861
return t.s.vm.subRunAll(omitNil, path, value, func(te *TagExpr, err error) error {
871862
if err != nil {
872863
return err

tagexpr_test.go

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -226,10 +226,11 @@ func Test(t *testing.T) {
226226
t.Fatalf("Eval Serial: %d, selector: %q, got: %v, expect: %v", i, selector, val, value)
227227
}
228228
}
229-
tagExpr.Range(func(path string, es ExprSelector, eval func() interface{}) error {
229+
tagExpr.Range(func(eh *ExprHandler) error {
230+
es := eh.ExprSelector()
230231
t.Logf("Range selector: %s, field: %q exprName: %q", es, es.Field(), es.Name())
231232
value := c.tests[es.String()]
232-
val := eval()
233+
val := eh.Eval()
233234
if !reflect.DeepEqual(val, value) {
234235
t.Fatalf("Range NO: %d, selector: %q, got: %v, expect: %v", i, es, val, value)
235236
}
@@ -542,10 +543,11 @@ func TestOperator(t *testing.T) {
542543
t.Fatalf("Eval NO: %d, selector: %q, got: %v, expect: %v", i, selector, val, value)
543544
}
544545
}
545-
tagExpr.Range(func(path string, es ExprSelector, eval func() interface{}) error {
546+
tagExpr.Range(func(eh *ExprHandler) error {
547+
es := eh.ExprSelector()
546548
t.Logf("Range selector: %s, field: %q exprName: %q", es, es.Field(), es.Name())
547549
value := c.tests[es.String()]
548-
val := eval()
550+
val := eh.Eval()
549551
if !reflect.DeepEqual(val, value) {
550552
t.Fatalf("Range NO: %d, selector: %q, got: %v, expect: %v", i, es, val, value)
551553
}
@@ -575,9 +577,10 @@ func TestStruct(t *testing.T) {
575577
assert.Equal(t, "xxx", expr.EvalString("B.C3"))
576578
assert.Equal(t, "xxx", expr.EvalString("B.C"))
577579
assert.Equal(t, "xxx", expr.EvalString("B.C.D.X"))
578-
expr.Range(func(path string, es ExprSelector, eval func() interface{}) error {
579-
t.Logf("Range selector: %s, field: %q exprName: %q", path, es.Field(), es.Name())
580-
if eval().(string) != "xxx" {
580+
expr.Range(func(eh *ExprHandler) error {
581+
es := eh.ExprSelector()
582+
t.Logf("Range selector: %s, field: %q exprName: %q", es, es.Field(), es.Name())
583+
if eh.Eval().(string) != "xxx" {
581584
t.FailNow()
582585
}
583586
return nil
@@ -669,8 +672,9 @@ func TestStruct3(t *testing.T) {
669672
if expr.EvalString("XBlock.BlockType") != "BlockType" {
670673
t.Fatal(expr.EvalString("XBlock.BlockType"))
671674
}
672-
err := expr.Range(func(path string, es ExprSelector, eval func() interface{}) error {
673-
t.Logf("Range selector: %s, field: %q exprName: %q, eval: %v", path, es.Field(), es.Name(), eval())
675+
err := expr.Range(func(eh *ExprHandler) error {
676+
es := eh.ExprSelector()
677+
t.Logf("Range selector: %s, field: %q exprName: %q, eval: %v", eh.Path(), es.Field(), es.Name(), eh.Eval())
674678
return nil
675679
})
676680
assert.NoError(t, err)
@@ -685,10 +689,10 @@ func TestNilField(t *testing.T) {
685689
}
686690
vm := New("tagexpr")
687691
te := vm.MustRun(P{})
688-
te.Range(func(path string, es ExprSelector, eval func() interface{}) error {
689-
r := eval()
692+
te.Range(func(eh *ExprHandler) error {
693+
r := eh.Eval()
690694
if r != nil {
691-
t.Fatal(path, r)
695+
t.Fatal(eh.Path(), r)
692696
}
693697
return nil
694698
})
@@ -701,10 +705,10 @@ func TestNilField(t *testing.T) {
701705
Nil1: new(int),
702706
Nil2: new(int),
703707
}
704-
vm.MustRun(g).Range(func(path string, es ExprSelector, eval func() interface{}) error {
705-
r, ok := eval().(bool)
708+
vm.MustRun(g).Range(func(eh *ExprHandler) error {
709+
r, ok := eh.Eval().(bool)
706710
if !ok || !r {
707-
t.Fatal(path, r)
711+
t.Fatal(eh.Path(), r)
708712
}
709713
return nil
710714
})
@@ -733,12 +737,12 @@ func TestNilField(t *testing.T) {
733737
SI: []interface{}{&M{X: "nn"}},
734738
}
735739
var cnt int
736-
vm.MustRun(n).Range(func(path string, es ExprSelector, eval func() interface{}) error {
737-
r, ok := eval().(bool)
740+
vm.MustRun(n).Range(func(eh *ExprHandler) error {
741+
r, ok := eh.Eval().(bool)
738742
if !ok || !r {
739-
t.Fatal(path, r)
743+
t.Fatal(eh.Path(), r)
740744
}
741-
t.Log("path:", path, "es:", es, "val:", r)
745+
t.Log("path:", eh.Path(), "es:", eh.ExprSelector(), "val:", r)
742746
cnt++
743747
return nil
744748
})
@@ -781,11 +785,11 @@ func TestDeepNested(t *testing.T) {
781785
expectValue := [...]interface{}{"I:address", nil, "A:address", nil, "X:address"}
782786
var i int
783787
vm := New("tagexpr")
784-
vm.MustRun(data).Range(func(path string, es ExprSelector, eval func() interface{}) error {
785-
assert.Equal(t, expectKey[i], path)
786-
assert.Equal(t, expectValue[i], eval())
788+
vm.MustRun(data).Range(func(eh *ExprHandler) error {
789+
assert.Equal(t, expectKey[i], eh.Path())
790+
assert.Equal(t, expectValue[i], eh.Eval())
787791
i++
788-
t.Log(path, es, eval())
792+
t.Log(eh.Path(), eh.ExprSelector(), eh.Eval())
789793
return nil
790794
})
791795
assert.Equal(t, 5, i)
@@ -809,16 +813,16 @@ func TestIssue3(t *testing.T) {
809813
},
810814
}
811815
vm := New("vd")
812-
err := vm.MustRun(a).Range(func(path string, es ExprSelector, eval func() interface{}) error {
813-
switch path {
816+
err := vm.MustRun(a).Range(func(eh *ExprHandler) error {
817+
switch eh.Path() {
814818
case "F1.Index":
815-
assert.Equal(t, float64(1), eval(), path)
819+
assert.Equal(t, float64(1), eh.Eval(), eh.Path())
816820
case "F2.Index":
817-
assert.Equal(t, nil, eval(), path)
821+
assert.Equal(t, nil, eh.Eval(), eh.Path())
818822
case "F1.P":
819-
assert.Equal(t, true, eval(), path)
823+
assert.Equal(t, true, eh.Eval(), eh.Path())
820824
case "F2.P":
821-
assert.Equal(t, false, eval(), path)
825+
assert.Equal(t, false, eh.Eval(), eh.Path())
822826
}
823827
return nil
824828
})

0 commit comments

Comments
 (0)