Skip to content

Commit d173a35

Browse files
Dean KarnDean Karn
authored andcommitted
Merge pull request #172 from joeybloggs/v8-development
Expose Methods for custom functions
2 parents 0f4bcfc + 95e8b47 commit d173a35

File tree

4 files changed

+73
-65
lines changed

4 files changed

+73
-65
lines changed

baked_in.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ func contains(v *Validate, topStruct reflect.Value, currentStructOrField reflect
260260

261261
func isNeField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
262262

263-
currentField, currentKind, ok := v.getStructFieldOK(currentStructOrField, param)
263+
currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param)
264264

265265
if !ok || currentKind != fieldKind {
266266
return true
@@ -307,7 +307,7 @@ func isNe(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Val
307307

308308
func isLteCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
309309

310-
topField, topKind, ok := v.getStructFieldOK(topStruct, param)
310+
topField, topKind, ok := v.GetStructFieldOK(topStruct, param)
311311
if !ok || topKind != fieldKind {
312312
return false
313313
}
@@ -348,7 +348,7 @@ func isLteCrossStructField(v *Validate, topStruct reflect.Value, current reflect
348348

349349
func isLtCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
350350

351-
topField, topKind, ok := v.getStructFieldOK(topStruct, param)
351+
topField, topKind, ok := v.GetStructFieldOK(topStruct, param)
352352
if !ok || topKind != fieldKind {
353353
return false
354354
}
@@ -389,7 +389,7 @@ func isLtCrossStructField(v *Validate, topStruct reflect.Value, current reflect.
389389

390390
func isGteCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
391391

392-
topField, topKind, ok := v.getStructFieldOK(topStruct, param)
392+
topField, topKind, ok := v.GetStructFieldOK(topStruct, param)
393393
if !ok || topKind != fieldKind {
394394
return false
395395
}
@@ -430,7 +430,7 @@ func isGteCrossStructField(v *Validate, topStruct reflect.Value, current reflect
430430

431431
func isGtCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
432432

433-
topField, topKind, ok := v.getStructFieldOK(topStruct, param)
433+
topField, topKind, ok := v.GetStructFieldOK(topStruct, param)
434434
if !ok || topKind != fieldKind {
435435
return false
436436
}
@@ -471,7 +471,7 @@ func isGtCrossStructField(v *Validate, topStruct reflect.Value, current reflect.
471471

472472
func isNeCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
473473

474-
topField, currentKind, ok := v.getStructFieldOK(topStruct, param)
474+
topField, currentKind, ok := v.GetStructFieldOK(topStruct, param)
475475
if !ok || currentKind != fieldKind {
476476
return true
477477
}
@@ -512,7 +512,7 @@ func isNeCrossStructField(v *Validate, topStruct reflect.Value, current reflect.
512512

513513
func isEqCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
514514

515-
topField, topKind, ok := v.getStructFieldOK(topStruct, param)
515+
topField, topKind, ok := v.GetStructFieldOK(topStruct, param)
516516
if !ok || topKind != fieldKind {
517517
return false
518518
}
@@ -553,7 +553,7 @@ func isEqCrossStructField(v *Validate, topStruct reflect.Value, current reflect.
553553

554554
func isEqField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
555555

556-
currentField, currentKind, ok := v.getStructFieldOK(currentStructOrField, param)
556+
currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param)
557557
if !ok || currentKind != fieldKind {
558558
return false
559559
}
@@ -718,7 +718,7 @@ func hasValue(v *Validate, topStruct reflect.Value, currentStructOrField reflect
718718

719719
func isGteField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
720720

721-
currentField, currentKind, ok := v.getStructFieldOK(currentStructOrField, param)
721+
currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param)
722722
if !ok || currentKind != fieldKind {
723723
return false
724724
}
@@ -759,7 +759,7 @@ func isGteField(v *Validate, topStruct reflect.Value, currentStructOrField refle
759759

760760
func isGtField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
761761

762-
currentField, currentKind, ok := v.getStructFieldOK(currentStructOrField, param)
762+
currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param)
763763
if !ok || currentKind != fieldKind {
764764
return false
765765
}
@@ -927,7 +927,7 @@ func hasMinOf(v *Validate, topStruct reflect.Value, currentStructOrField reflect
927927

928928
func isLteField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
929929

930-
currentField, currentKind, ok := v.getStructFieldOK(currentStructOrField, param)
930+
currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param)
931931
if !ok || currentKind != fieldKind {
932932
return false
933933
}
@@ -968,7 +968,7 @@ func isLteField(v *Validate, topStruct reflect.Value, currentStructOrField refle
968968

969969
func isLtField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
970970

971-
currentField, currentKind, ok := v.getStructFieldOK(currentStructOrField, param)
971+
currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param)
972972
if !ok || currentKind != fieldKind {
973973
return false
974974
}

util.go

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ var (
2929
}
3030
)
3131

32-
func (v *Validate) extractType(current reflect.Value) (reflect.Value, reflect.Kind) {
32+
// ExtractType gets the actual underlying type of field value.
33+
// It will dive into pointers, customTypes and return you the
34+
// underlying value and it's kind.
35+
// it is exposed for use within you Custom Functions
36+
func (v *Validate) ExtractType(current reflect.Value) (reflect.Value, reflect.Kind) {
3337

3438
switch current.Kind() {
3539
case reflect.Ptr:
@@ -38,15 +42,15 @@ func (v *Validate) extractType(current reflect.Value) (reflect.Value, reflect.Ki
3842
return current, reflect.Ptr
3943
}
4044

41-
return v.extractType(current.Elem())
45+
return v.ExtractType(current.Elem())
4246

4347
case reflect.Interface:
4448

4549
if current.IsNil() {
4650
return current, reflect.Interface
4751
}
4852

49-
return v.extractType(current.Elem())
53+
return v.ExtractType(current.Elem())
5054

5155
case reflect.Invalid:
5256
return current, reflect.Invalid
@@ -55,17 +59,21 @@ func (v *Validate) extractType(current reflect.Value) (reflect.Value, reflect.Ki
5559

5660
if v.hasCustomFuncs {
5761
if fn, ok := v.customTypeFuncs[current.Type()]; ok {
58-
return v.extractType(reflect.ValueOf(fn(current)))
62+
return v.ExtractType(reflect.ValueOf(fn(current)))
5963
}
6064
}
6165

6266
return current, current.Kind()
6367
}
6468
}
6569

66-
func (v *Validate) getStructFieldOK(current reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool) {
70+
// GetStructFieldOK traverses a struct to retrieve a specific field denoted by the provided namespace and
71+
// returns the field, field kind and whether is was successful in retrieving the field at all.
72+
// NOTE: when not successful ok will be false, this can happen when a nested struct is nil and so the field
73+
// could not be retrived because it didnt exist.
74+
func (v *Validate) GetStructFieldOK(current reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool) {
6775

68-
current, kind := v.extractType(current)
76+
current, kind := v.ExtractType(current)
6977

7078
if kind == reflect.Invalid {
7179
return current, kind, false
@@ -108,7 +116,7 @@ func (v *Validate) getStructFieldOK(current reflect.Value, namespace string) (re
108116

109117
current = current.FieldByName(fld)
110118

111-
return v.getStructFieldOK(current, ns)
119+
return v.GetStructFieldOK(current, ns)
112120
}
113121

114122
case reflect.Array, reflect.Slice:
@@ -129,7 +137,7 @@ func (v *Validate) getStructFieldOK(current reflect.Value, namespace string) (re
129137
}
130138
}
131139

132-
return v.getStructFieldOK(current.Index(arrIdx), namespace[startIdx:])
140+
return v.GetStructFieldOK(current.Index(arrIdx), namespace[startIdx:])
133141

134142
case reflect.Map:
135143
idx := strings.Index(namespace, leftBracket) + 1
@@ -148,47 +156,47 @@ func (v *Validate) getStructFieldOK(current reflect.Value, namespace string) (re
148156
switch current.Type().Key().Kind() {
149157
case reflect.Int:
150158
i, _ := strconv.Atoi(key)
151-
return v.getStructFieldOK(current.MapIndex(reflect.ValueOf(i)), namespace[endIdx+1:])
159+
return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(i)), namespace[endIdx+1:])
152160
case reflect.Int8:
153161
i, _ := strconv.ParseInt(key, 10, 8)
154-
return v.getStructFieldOK(current.MapIndex(reflect.ValueOf(int8(i))), namespace[endIdx+1:])
162+
return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(int8(i))), namespace[endIdx+1:])
155163
case reflect.Int16:
156164
i, _ := strconv.ParseInt(key, 10, 16)
157-
return v.getStructFieldOK(current.MapIndex(reflect.ValueOf(int16(i))), namespace[endIdx+1:])
165+
return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(int16(i))), namespace[endIdx+1:])
158166
case reflect.Int32:
159167
i, _ := strconv.ParseInt(key, 10, 32)
160-
return v.getStructFieldOK(current.MapIndex(reflect.ValueOf(int32(i))), namespace[endIdx+1:])
168+
return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(int32(i))), namespace[endIdx+1:])
161169
case reflect.Int64:
162170
i, _ := strconv.ParseInt(key, 10, 64)
163-
return v.getStructFieldOK(current.MapIndex(reflect.ValueOf(i)), namespace[endIdx+1:])
171+
return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(i)), namespace[endIdx+1:])
164172
case reflect.Uint:
165173
i, _ := strconv.ParseUint(key, 10, 0)
166-
return v.getStructFieldOK(current.MapIndex(reflect.ValueOf(uint(i))), namespace[endIdx+1:])
174+
return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(uint(i))), namespace[endIdx+1:])
167175
case reflect.Uint8:
168176
i, _ := strconv.ParseUint(key, 10, 8)
169-
return v.getStructFieldOK(current.MapIndex(reflect.ValueOf(uint8(i))), namespace[endIdx+1:])
177+
return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(uint8(i))), namespace[endIdx+1:])
170178
case reflect.Uint16:
171179
i, _ := strconv.ParseUint(key, 10, 16)
172-
return v.getStructFieldOK(current.MapIndex(reflect.ValueOf(uint16(i))), namespace[endIdx+1:])
180+
return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(uint16(i))), namespace[endIdx+1:])
173181
case reflect.Uint32:
174182
i, _ := strconv.ParseUint(key, 10, 32)
175-
return v.getStructFieldOK(current.MapIndex(reflect.ValueOf(uint32(i))), namespace[endIdx+1:])
183+
return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(uint32(i))), namespace[endIdx+1:])
176184
case reflect.Uint64:
177185
i, _ := strconv.ParseUint(key, 10, 64)
178-
return v.getStructFieldOK(current.MapIndex(reflect.ValueOf(i)), namespace[endIdx+1:])
186+
return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(i)), namespace[endIdx+1:])
179187
case reflect.Float32:
180188
f, _ := strconv.ParseFloat(key, 32)
181-
return v.getStructFieldOK(current.MapIndex(reflect.ValueOf(float32(f))), namespace[endIdx+1:])
189+
return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(float32(f))), namespace[endIdx+1:])
182190
case reflect.Float64:
183191
f, _ := strconv.ParseFloat(key, 64)
184-
return v.getStructFieldOK(current.MapIndex(reflect.ValueOf(f)), namespace[endIdx+1:])
192+
return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(f)), namespace[endIdx+1:])
185193
case reflect.Bool:
186194
b, _ := strconv.ParseBool(key)
187-
return v.getStructFieldOK(current.MapIndex(reflect.ValueOf(b)), namespace[endIdx+1:])
195+
return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(b)), namespace[endIdx+1:])
188196

189197
// reflect.Type = string
190198
default:
191-
return v.getStructFieldOK(current.MapIndex(reflect.ValueOf(key)), namespace[endIdx+1:])
199+
return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(key)), namespace[endIdx+1:])
192200
}
193201
}
194202

validator.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ func (v *Validate) FieldWithValue(val interface{}, field interface{}, tag string
282282
func (v *Validate) StructPartial(current interface{}, fields ...string) error {
283283
v.initCheck()
284284

285-
sv, _ := v.extractType(reflect.ValueOf(current))
285+
sv, _ := v.ExtractType(reflect.ValueOf(current))
286286
name := sv.Type().Name()
287287
m := map[string]*struct{}{}
288288

@@ -340,7 +340,7 @@ func (v *Validate) StructPartial(current interface{}, fields ...string) error {
340340
func (v *Validate) StructExcept(current interface{}, fields ...string) error {
341341
v.initCheck()
342342

343-
sv, _ := v.extractType(reflect.ValueOf(current))
343+
sv, _ := v.ExtractType(reflect.ValueOf(current))
344344
name := sv.Type().Name()
345345
m := map[string]*struct{}{}
346346

@@ -435,7 +435,7 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect.
435435
v.tagsCache.Set(tag, cTag)
436436
}
437437

438-
current, kind := v.extractType(current)
438+
current, kind := v.ExtractType(current)
439439
var typ reflect.Type
440440

441441
switch kind {

0 commit comments

Comments
 (0)