@@ -11,6 +11,7 @@ import (
1111// underlying value and it's kind.
1212func (v * validate ) extractTypeInternal (current reflect.Value , nullable bool ) (reflect.Value , reflect.Kind , bool ) {
1313
14+ BEGIN:
1415 switch current .Kind () {
1516 case reflect .Ptr :
1617
@@ -20,7 +21,8 @@ func (v *validate) extractTypeInternal(current reflect.Value, nullable bool) (re
2021 return current , reflect .Ptr , nullable
2122 }
2223
23- return v .extractTypeInternal (current .Elem (), nullable )
24+ current = current .Elem ()
25+ goto BEGIN
2426
2527 case reflect .Interface :
2628
@@ -30,7 +32,8 @@ func (v *validate) extractTypeInternal(current reflect.Value, nullable bool) (re
3032 return current , reflect .Interface , nullable
3133 }
3234
33- return v .extractTypeInternal (current .Elem (), nullable )
35+ current = current .Elem ()
36+ goto BEGIN
3437
3538 case reflect .Invalid :
3639 return current , reflect .Invalid , nullable
@@ -40,7 +43,8 @@ func (v *validate) extractTypeInternal(current reflect.Value, nullable bool) (re
4043 if v .v .hasCustomFuncs {
4144
4245 if fn , ok := v .v .customFuncs [current .Type ()]; ok {
43- return v .extractTypeInternal (reflect .ValueOf (fn (current )), nullable )
46+ current = reflect .ValueOf (fn (current ))
47+ goto BEGIN
4448 }
4549 }
4650
@@ -53,23 +57,24 @@ func (v *validate) extractTypeInternal(current reflect.Value, nullable bool) (re
5357//
5458// NOTE: when not successful ok will be false, this can happen when a nested struct is nil and so the field
5559// could not be retrieved because it didn't exist.
56- func (v * validate ) getStructFieldOKInternal (current reflect.Value , namespace string ) (reflect.Value , reflect.Kind , bool ) {
60+ func (v * validate ) getStructFieldOKInternal (val reflect.Value , namespace string ) (current reflect.Value , kind reflect.Kind , found bool ) {
5761
58- current , kind , _ := v .ExtractType (current )
62+ BEGIN:
63+ current , kind , _ = v .ExtractType (val )
5964
6065 if kind == reflect .Invalid {
61- return current , kind , false
66+ return
6267 }
6368
6469 if namespace == "" {
65- return current , kind , true
70+ found = true
71+ return
6672 }
6773
6874 switch kind {
6975
7076 case reflect .Ptr , reflect .Interface :
71-
72- return current , kind , false
77+ return
7378
7479 case reflect .Struct :
7580
@@ -95,9 +100,9 @@ func (v *validate) getStructFieldOKInternal(current reflect.Value, namespace str
95100 ns = namespace [bracketIdx :]
96101 }
97102
98- current = current .FieldByName (fld )
99-
100- return v . getStructFieldOKInternal ( current , ns )
103+ val = current .FieldByName (fld )
104+ namespace = ns
105+ goto BEGIN
101106 }
102107
103108 case reflect .Array , reflect .Slice :
@@ -118,7 +123,9 @@ func (v *validate) getStructFieldOKInternal(current reflect.Value, namespace str
118123 }
119124 }
120125
121- return v .getStructFieldOKInternal (current .Index (arrIdx ), namespace [startIdx :])
126+ val = current .Index (arrIdx )
127+ namespace = namespace [startIdx :]
128+ goto BEGIN
122129
123130 case reflect .Map :
124131 idx := strings .Index (namespace , leftBracket ) + 1
@@ -137,48 +144,76 @@ func (v *validate) getStructFieldOKInternal(current reflect.Value, namespace str
137144 switch current .Type ().Key ().Kind () {
138145 case reflect .Int :
139146 i , _ := strconv .Atoi (key )
140- return v .getStructFieldOKInternal (current .MapIndex (reflect .ValueOf (i )), namespace [endIdx + 1 :])
147+ val = current .MapIndex (reflect .ValueOf (i ))
148+ namespace = namespace [endIdx + 1 :]
149+
141150 case reflect .Int8 :
142151 i , _ := strconv .ParseInt (key , 10 , 8 )
143- return v .getStructFieldOKInternal (current .MapIndex (reflect .ValueOf (int8 (i ))), namespace [endIdx + 1 :])
152+ val = current .MapIndex (reflect .ValueOf (int8 (i )))
153+ namespace = namespace [endIdx + 1 :]
154+
144155 case reflect .Int16 :
145156 i , _ := strconv .ParseInt (key , 10 , 16 )
146- return v .getStructFieldOKInternal (current .MapIndex (reflect .ValueOf (int16 (i ))), namespace [endIdx + 1 :])
157+ val = current .MapIndex (reflect .ValueOf (int16 (i )))
158+ namespace = namespace [endIdx + 1 :]
159+
147160 case reflect .Int32 :
148161 i , _ := strconv .ParseInt (key , 10 , 32 )
149- return v .getStructFieldOKInternal (current .MapIndex (reflect .ValueOf (int32 (i ))), namespace [endIdx + 1 :])
162+ val = current .MapIndex (reflect .ValueOf (int32 (i )))
163+ namespace = namespace [endIdx + 1 :]
164+
150165 case reflect .Int64 :
151166 i , _ := strconv .ParseInt (key , 10 , 64 )
152- return v .getStructFieldOKInternal (current .MapIndex (reflect .ValueOf (i )), namespace [endIdx + 1 :])
167+ val = current .MapIndex (reflect .ValueOf (i ))
168+ namespace = namespace [endIdx + 1 :]
169+
153170 case reflect .Uint :
154171 i , _ := strconv .ParseUint (key , 10 , 0 )
155- return v .getStructFieldOKInternal (current .MapIndex (reflect .ValueOf (uint (i ))), namespace [endIdx + 1 :])
172+ val = current .MapIndex (reflect .ValueOf (uint (i )))
173+ namespace = namespace [endIdx + 1 :]
174+
156175 case reflect .Uint8 :
157176 i , _ := strconv .ParseUint (key , 10 , 8 )
158- return v .getStructFieldOKInternal (current .MapIndex (reflect .ValueOf (uint8 (i ))), namespace [endIdx + 1 :])
177+ val = current .MapIndex (reflect .ValueOf (uint8 (i )))
178+ namespace = namespace [endIdx + 1 :]
179+
159180 case reflect .Uint16 :
160181 i , _ := strconv .ParseUint (key , 10 , 16 )
161- return v .getStructFieldOKInternal (current .MapIndex (reflect .ValueOf (uint16 (i ))), namespace [endIdx + 1 :])
182+ val = current .MapIndex (reflect .ValueOf (uint16 (i )))
183+ namespace = namespace [endIdx + 1 :]
184+
162185 case reflect .Uint32 :
163186 i , _ := strconv .ParseUint (key , 10 , 32 )
164- return v .getStructFieldOKInternal (current .MapIndex (reflect .ValueOf (uint32 (i ))), namespace [endIdx + 1 :])
187+ val = current .MapIndex (reflect .ValueOf (uint32 (i )))
188+ namespace = namespace [endIdx + 1 :]
189+
165190 case reflect .Uint64 :
166191 i , _ := strconv .ParseUint (key , 10 , 64 )
167- return v .getStructFieldOKInternal (current .MapIndex (reflect .ValueOf (i )), namespace [endIdx + 1 :])
192+ val = current .MapIndex (reflect .ValueOf (i ))
193+ namespace = namespace [endIdx + 1 :]
194+
168195 case reflect .Float32 :
169196 f , _ := strconv .ParseFloat (key , 32 )
170- return v .getStructFieldOKInternal (current .MapIndex (reflect .ValueOf (float32 (f ))), namespace [endIdx + 1 :])
197+ val = current .MapIndex (reflect .ValueOf (float32 (f )))
198+ namespace = namespace [endIdx + 1 :]
199+
171200 case reflect .Float64 :
172201 f , _ := strconv .ParseFloat (key , 64 )
173- return v .getStructFieldOKInternal (current .MapIndex (reflect .ValueOf (f )), namespace [endIdx + 1 :])
202+ val = current .MapIndex (reflect .ValueOf (f ))
203+ namespace = namespace [endIdx + 1 :]
204+
174205 case reflect .Bool :
175206 b , _ := strconv .ParseBool (key )
176- return v .getStructFieldOKInternal (current .MapIndex (reflect .ValueOf (b )), namespace [endIdx + 1 :])
207+ val = current .MapIndex (reflect .ValueOf (b ))
208+ namespace = namespace [endIdx + 1 :]
177209
178210 // reflect.Type = string
179211 default :
180- return v .getStructFieldOKInternal (current .MapIndex (reflect .ValueOf (key )), namespace [endIdx + 1 :])
212+ val = current .MapIndex (reflect .ValueOf (key ))
213+ namespace = namespace [endIdx + 1 :]
181214 }
215+
216+ goto BEGIN
182217 }
183218
184219 // if got here there was more namespace, cannot go any deeper
0 commit comments