diff --git a/cache.go b/cache.go index 655b522..6445b78 100644 --- a/cache.go +++ b/cache.go @@ -8,73 +8,6 @@ import ( "sync/atomic" ) -// type cachedField struct { -// Idx int -// Name string -// AltName string -// CachedTag *cachedTag -// } - -// type cachedStruct struct { -// Name string -// fields map[int]cachedField -// } - -// type structCacheMap struct { -// lock sync.RWMutex -// m map[reflect.Type]*cachedStruct -// } - -// func (s *structCacheMap) Get(key reflect.Type) (*cachedStruct, bool) { -// s.lock.RLock() -// value, ok := s.m[key] -// s.lock.RUnlock() -// return value, ok -// } - -// func (s *structCacheMap) Set(key reflect.Type, value *cachedStruct) { -// s.lock.Lock() -// s.m[key] = value -// s.lock.Unlock() -// } - -// type cachedTag struct { -// tag string -// isOmitEmpty bool -// isNoStructLevel bool -// isStructOnly bool -// diveTag string -// tags []*tagVals -// } - -// type tagVals struct { -// tagVals [][]string -// isOrVal bool -// isAlias bool -// tag string -// } - -// type tagCacheMap struct { -// lock sync.RWMutex -// m map[string]*cachedTag -// } - -// func (s *tagCacheMap) Get(key string) (*cachedTag, bool) { -// s.lock.RLock() -// value, ok := s.m[key] -// s.lock.RUnlock() - -// return value, ok -// } - -// func (s *tagCacheMap) Set(key string, value *cachedTag) { -// s.lock.Lock() -// s.m[key] = value -// s.lock.Unlock() -// } - -// ******* New Cache *************** - type structCache struct { lock sync.Mutex m atomic.Value // map[reflect.Type]*cStruct @@ -156,7 +89,7 @@ type cTag struct { func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStruct { v.structCache.lock.Lock() - defer v.structCache.lock.Unlock() + defer v.structCache.lock.Unlock() // leave as defer! because if inner panics, it will never get unlocked otherwise! typ := current.Type() @@ -164,7 +97,6 @@ func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStr // isn't parsed again. cs, ok := v.structCache.Get(typ) if ok { - // v.structCache.lock.Unlock() return cs } @@ -181,14 +113,12 @@ func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStr fld = typ.Field(i) - // if fld.PkgPath != blank { if !fld.Anonymous && fld.PkgPath != blank { continue } tag = fld.Tag.Get(v.tagName) - // if len(tag) == 0 || tag == skipValidationTag { if tag == skipValidationTag { continue } @@ -205,24 +135,8 @@ func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStr } } - // fmt.Println("Finding Struct Tag", sName, "FLD:", fld.Name) - // ctag, ok := v.tagCache.Get(tag) - // if !ok { - // fmt.Println("Not Found, Lock then check again for parallel operations") - // v.tagCache.lock.Lock() - // defer func() { - // fmt.Println("Ulocking") - // v.tagCache.lock.Unlock() - // fmt.Println("Unlocked") - // }() - // defer v.tagCache.lock.Unlock() - - // if ctag, ok = v.tagCache.Get(tag); !ok { - - // fmt.Println("parsing tag", tag) - // ctag = v.parseFieldTags(tag, fld.Name) - // NOTE: cannot use tag cache, because tag may be equal, but things like alias may be different - // and so only struct level caching can be used + // NOTE: cannot use shared tag cache, because tags may be equal, but things like alias may be different + // and so only struct level caching can be used instead of combined with Field tag caching if len(tag) > 0 { ctag, _ = v.parseFieldTagsRecursive(tag, fld.Name, blank, false) @@ -231,141 +145,48 @@ func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStr // elements of the field. ctag = new(cTag) } - // fmt.Println("Done Parsing") - // v.tagCache.Set(tag, ctag) - // fmt.Println("Tag Cahed") - // } - - // fmt.Println("Ulocking") - // v.tagCache.lock.Unlock() - // fmt.Println("Unlocked") - // } - - // fmt.Println(tag, ctag) cs.fields[i] = &cField{Idx: i, Name: fld.Name, AltName: customName, cTags: ctag} } - // If not anonymous type; they have to be parsed every time because if interface - // a different struct could be used... - // if len(sName) > 0 { - // fmt.Println(typ) v.structCache.Set(typ, cs) - // } - - // v.structCache.lock.Unlock() return cs } -// func (v *Validate) parseFieldTags(tag, fieldName string) (ctag *cTag) { - -// // ctag := &cTag{tag: tag} - -// // fmt.Println(tag) -// ctag, _ = v.parseFieldTagsRecursive(tag, fieldName, blank, false) - -// v.tagCache.Set(tag, ctag) - -// // fmt.Println(ctag) -// return -// } - // TODO: Optimize for to not Split but ust for over string chunk, by chunk func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias string, hasAlias bool) (firstCtag *cTag, current *cTag) { - // func (v *Validate) parseFieldTagsRecursive(ctag *cTag, tag, fieldName, alias string, isAlias bool) bool { - // if tag == blank { - // return - // } - // fmt.Println("Parsing, depath:", depth) var t string var ok bool noAlias := len(alias) == 0 - // var tmpCtag *cTag - // var start,end int - // var ctag *cTag - // var lastCtag *cTag - // ctag := &cTag{tag: tag} tags := strings.Split(tag, tagSeparator) - // fmt.Println(len(tags), tags) - for i := 0; i < len(tags); i++ { - // for i := 0; i < len(tags); i++ { t = tags[i] if noAlias { alias = t } - // _, found := v.aliasValidators[t] - // fmt.Println(i, t, found) - - // if len(t) == 0 { - // continue - // } - // if i == 0 { - // current = &cTag{aliasTag: alias, hasAlias: hasAlias} - // firstCtag = current - // } else { - // current.next = &cTag{aliasTag: alias, hasAlias: hasAlias} - // current = current.next - // } if v.hasAliasValidators { // check map for alias and process new tags, otherwise process as usual if tagsVal, found := v.aliasValidators[t]; found { - // fmt.Println(tagsVal) - if i == 0 { firstCtag, current = v.parseFieldTagsRecursive(tagsVal, fieldName, t, true) } else { - // fmt.Println("BEFORE ALIAS:", current) - // diveCurr := current next, curr := v.parseFieldTagsRecursive(tagsVal, fieldName, t, true) - // fmt.Println("ALIAS:", next, curr) current.next, current = next, curr - // fmt.Println("AFTER current", diveCurr) - // current.next, current = v.parseFieldTagsRecursive(tagsVal, fieldName, t, true) } continue - - // // tmpCtag, lastCtag = v.parseFieldTagsRecursive(tagsVal, fieldName, t, true) - - // // if ctag == nil { - // // ctag = tmpCtag - // // } else { - // // ctag.next = tmpCtag - // // } } } - // if i == 0 { - // firstCtag = current - // } - - // type cTag struct { - // tag string - // aliasTag string - // hasAlias bool - // isOmitEmpty bool - // isNoStructLevel bool - // isStructOnly bool - // isDive bool - // isOrVal bool - // fn Func - // next *cTag - // } - - // if lastCtag == nil { - // lastCtag = ctag - // } - if i == 0 { current = &cTag{aliasTag: alias, hasAlias: hasAlias, hasTag: true} firstCtag = current @@ -378,12 +199,7 @@ func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias s case diveTag: current.isDive = true - // fmt.Println("DIVE CURRENT", current) continue - // cTag.diveTag = tag - // tVals := &tagVals{tagVals: [][]string{{t}}} - // cTag.tags = append(cTag.tags, tVals) - // return true case omitempty: current.isOmitEmpty = true @@ -406,45 +222,7 @@ func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias s // if a pipe character is needed within the param you must use the utf8Pipe representation "0x7C" orVals := strings.Split(t, orSeparator) - // // if no or values - // if len(orVals) == 1 { - // current.fn, ok = v.validationFuncs[t] - // if !ok { - // panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, fieldName))) - // } - - // } else { - - // tagVal := &tagVals{isAlias: isAlias, isOrVal: len(orVals) > 1, tagVals: make([][]string, len(orVals))} - // cTag.tags = append(cTag.tags, tagVal) - - // var key string - // var param string - for j := 0; j < len(orVals); j++ { - // for i, val := range orVals { - - // if v.hasAliasValidators { - // // check map for alias and process new tags, otherwise process as usual - // if tagsVal, ok := v.aliasValidators[orVals[j]]; ok { - - // if i == 0 { - // firstCtag, current = v.parseFieldTagsRecursive(tagsVal, fieldName, orVals[j], true) - // } else { - // current.next, current = v.parseFieldTagsRecursive(tagsVal, fieldName, orVals[j], true) - // } - - // continue - - // // tmpCtag, lastCtag = v.parseFieldTagsRecursive(tagsVal, fieldName, t, true) - - // // if ctag == nil { - // // ctag = tmpCtag - // // } else { - // // ctag.next = tmpCtag - // // } - // } - // } vals := strings.SplitN(orVals[j], tagKeySeparator, 2) @@ -452,57 +230,31 @@ func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias s alias = vals[0] current.aliasTag = alias } else { - // alias = t current.actualAliasTag = t } if j > 0 { current.next = &cTag{aliasTag: alias, actualAliasTag: current.actualAliasTag, hasAlias: hasAlias, hasTag: true} current = current.next - // current.next=& } - // else{ + current.tag = vals[0] if len(current.tag) == 0 { panic(strings.TrimSpace(fmt.Sprintf(invalidValidation, fieldName))) } - // _, found := v.validationFuncs[current.tag] - // fmt.Println("TAG", current.tag, "FOund:", found) - if current.fn, ok = v.validationFuncs[current.tag]; !ok { - // fmt.Println("I'm panicing!") panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, fieldName))) } current.isOrVal = len(orVals) > 1 - // } - - // tagVal.tag = key - - // if isAlias { - // tagVal.tag = alias - // } - - // if key == blank { - // panic(strings.TrimSpace(fmt.Sprintf(invalidValidation, fieldName))) - // } if len(vals) > 1 { current.param = strings.Replace(strings.Replace(vals[1], utf8HexComma, ",", -1), utf8Pipe, "|", -1) } - - // tagVal.tagVals[i] = []string{key, param} } - // } } } - // if depth > 0 { - // // _, found := v.aliasValidators[t] - // fmt.Println("WTF", len(tags), tags, firstCtag, current) - // panic("WTF") - // } - return } diff --git a/util.go b/util.go index 07d59a0..1ecd8ee 100644 --- a/util.go +++ b/util.go @@ -7,7 +7,6 @@ import ( ) const ( - // dash = "-" blank = "" namespaceSeparator = "." leftBracket = "[" @@ -59,15 +58,10 @@ func (v *Validate) ExtractType(current reflect.Value) (reflect.Value, reflect.Ki default: if v.hasCustomFuncs { - // fmt.Println("Type", current.Type()) - if fn, ok := v.customTypeFuncs[current.Type()]; ok { - - // fmt.Println("OK") + if fn, ok := v.customTypeFuncs[current.Type()]; ok { return v.ExtractType(reflect.ValueOf(fn(current))) } - - // fmt.Println("NOT OK") } return current, current.Kind() @@ -245,136 +239,3 @@ func panicIf(err error) { panic(err.Error()) } } - -// func (v *Validate) parseStruct(current reflect.Value, sName string) *cachedStruct { - -// typ := current.Type() -// s := &cachedStruct{Name: sName, fields: map[int]cachedField{}} - -// numFields := current.NumField() - -// var fld reflect.StructField -// var tag string -// var customName string - -// for i := 0; i < numFields; i++ { - -// fld = typ.Field(i) - -// if fld.PkgPath != blank { -// continue -// } - -// tag = fld.Tag.Get(v.tagName) - -// if tag == skipValidationTag { -// continue -// } - -// customName = fld.Name -// if v.fieldNameTag != blank { - -// name := strings.SplitN(fld.Tag.Get(v.fieldNameTag), ",", 2)[0] - -// // dash check is for json "-" (aka skipValidationTag) means don't output in json -// if name != "" && name != skipValidationTag { -// customName = name -// } -// } - -// cTag, ok := v.oldTagCache.Get(tag) -// if !ok { -// cTag = v.parseTags(tag, fld.Name) -// } - -// s.fields[i] = cachedField{Idx: i, Name: fld.Name, AltName: customName, CachedTag: cTag} -// } - -// v.oldStructCache.Set(typ, s) - -// return s -// } - -// func (v *Validate) parseTags(tag, fieldName string) *cachedTag { - -// cTag := &cachedTag{tag: tag} - -// v.parseTagsRecursive(cTag, tag, fieldName, blank, false) - -// v.oldTagCache.Set(tag, cTag) - -// return cTag -// } - -// func (v *Validate) parseTagsRecursive(cTag *cachedTag, tag, fieldName, alias string, isAlias bool) bool { - -// if tag == blank { -// return true -// } - -// for _, t := range strings.Split(tag, tagSeparator) { - -// if v.hasAliasValidators { -// // check map for alias and process new tags, otherwise process as usual -// if tagsVal, ok := v.aliasValidators[t]; ok { - -// leave := v.parseTagsRecursive(cTag, tagsVal, fieldName, t, true) - -// if leave { -// return leave -// } - -// continue -// } -// } - -// switch t { - -// case diveTag: -// cTag.diveTag = tag -// tVals := &tagVals{tagVals: [][]string{{t}}} -// cTag.tags = append(cTag.tags, tVals) -// return true - -// case omitempty: -// cTag.isOmitEmpty = true - -// case structOnlyTag: -// cTag.isStructOnly = true - -// case noStructLevelTag: -// cTag.isNoStructLevel = true -// } - -// // if a pipe character is needed within the param you must use the utf8Pipe representation "0x7C" -// orVals := strings.Split(t, orSeparator) -// tagVal := &tagVals{isAlias: isAlias, isOrVal: len(orVals) > 1, tagVals: make([][]string, len(orVals))} -// cTag.tags = append(cTag.tags, tagVal) - -// var key string -// var param string - -// for i, val := range orVals { -// vals := strings.SplitN(val, tagKeySeparator, 2) -// key = vals[0] - -// tagVal.tag = key - -// if isAlias { -// tagVal.tag = alias -// } - -// if key == blank { -// panic(strings.TrimSpace(fmt.Sprintf(invalidValidation, fieldName))) -// } - -// if len(vals) > 1 { -// param = strings.Replace(strings.Replace(vals[1], utf8HexComma, ",", -1), utf8Pipe, "|", -1) -// } - -// tagVal.tagVals[i] = []string{key, param} -// } -// } - -// return false -// } diff --git a/validator.go b/validator.go index 73ba8f2..096365d 100644 --- a/validator.go +++ b/validator.go @@ -148,11 +148,9 @@ type Validate struct { hasCustomFuncs bool hasAliasValidators bool hasStructLevelFuncs bool - // oldTagCache *tagCacheMap - // oldStructCache *structCacheMap - tagCache *tagCache - structCache *structCache - errsPool *sync.Pool + tagCache *tagCache + structCache *structCache + errsPool *sync.Pool } func (v *Validate) initCheck() { @@ -234,8 +232,6 @@ func New(config *Config) *Validate { fieldNameTag: config.FieldNameTag, tagCache: tc, structCache: sc, - // oldTagCache: &tagCacheMap{m: map[string]*cachedTag{}}, - // oldStructCache: &structCacheMap{m: map[reflect.Type]*cachedStruct{}}, errsPool: &sync.Pool{New: func() interface{} { return ValidationErrors{} }}} @@ -364,8 +360,6 @@ func (v *Validate) Field(field interface{}, tag string) error { } } - // fmt.Println("CTAG:", ctag) - v.traverseField(fieldVal, fieldVal, fieldVal, blank, blank, errs, false, false, nil, nil, defaultCField, ctag) if len(errs) == 0 { @@ -400,6 +394,7 @@ func (v *Validate) FieldWithValue(val interface{}, field interface{}, tag string ctag, ok = v.tagCache.Get(tag) if !ok { ctag, _ = v.parseFieldTagsRecursive(tag, blank, blank, false) + v.tagCache.Set(tag, ctag) } } @@ -533,20 +528,15 @@ func (v *Validate) ensureValidStruct(topStruct reflect.Value, currentStruct refl // tranverseStruct traverses a structs fields and then passes them to be validated by traverseField func (v *Validate) tranverseStruct(topStruct reflect.Value, currentStruct reflect.Value, current reflect.Value, errPrefix string, nsPrefix string, errs ValidationErrors, useStructName bool, partial bool, exclude bool, includeExclude map[string]*struct{}, cs *cStruct, ct *cTag) { - // var ok bool + var ok bool first := len(nsPrefix) == 0 typ := current.Type() - var ok bool - - // var sName string cs, ok = v.structCache.Get(typ) if !ok { cs = v.extractStructCache(current, typ.Name()) } - // sName := typ.Name() - if useStructName { errPrefix += cs.Name + namespaceSeparator @@ -560,55 +550,6 @@ func (v *Validate) tranverseStruct(topStruct reflect.Value, currentStruct reflec // if present if first || ct == nil || !ct.isStructOnly { - // var fld reflect.StructField - - // is anonymous struct, cannot parse or cache as - // it has no name to index by - // if sName == blank { - - // var customName string - // var ok bool - // numFields := current.NumField() - - // for i := 0; i < numFields; i++ { - - // fld = typ.Field(i) - - // if !fld.Anonymous && fld.PkgPath != blank { - // continue - // } - - // if partial { - - // _, ok = includeExclude[errPrefix+fld.Name] - - // if (ok && exclude) || (!ok && !exclude) { - // continue - // } - // } - - // customName = fld.Name - - // if v.fieldNameTag != blank { - - // name := strings.SplitN(fld.Tag.Get(v.fieldNameTag), ",", 2)[0] - - // // dash check is for json "-" means don't output in json - // if name != blank && name != dash { - // customName = name - // } - // } - - // v.traverseField(topStruct, currentStruct, current.Field(i), errPrefix, nsPrefix, errs, true, fld.Tag.Get(v.tagName), fld.Name, customName, partial, exclude, includeExclude, nil) - // } - // } else { - // s, ok := v.oldStructCache.Get(typ) - // if !ok { - // s = v.parseStruct(current, sName) - // ccs := v.extractStructCache(current, sName) - // fmt.Println(ccs, ccs.fields[0], s.fields[0].CachedTag) - // } - for _, f := range cs.fields { if partial { @@ -619,48 +560,26 @@ func (v *Validate) tranverseStruct(topStruct reflect.Value, currentStruct reflec continue } } - // fld = typ.Field(f.Idx) - // fmt.Println(errPrefix+f.Name, f.cTags) v.traverseField(topStruct, currentStruct, current.Field(f.Idx), errPrefix, nsPrefix, errs, partial, exclude, includeExclude, cs, f, f.cTags) } - // } } // check if any struct level validations, after all field validations already checked. if cs.fn != nil { - // if fsn, ok := v.structLevelFuncs[current.Type()]; ok { cs.fn(v, &StructLevel{v: v, TopStruct: topStruct, CurrentStruct: current, errPrefix: errPrefix, nsPrefix: nsPrefix, errs: errs}) - // } } } // traverseField validates any field, be it a struct or single field, ensures it's validity and passes it along to be validated via it's tag options func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect.Value, current reflect.Value, errPrefix string, nsPrefix string, errs ValidationErrors, partial bool, exclude bool, includeExclude map[string]*struct{}, cs *cStruct, cf *cField, ct *cTag) { - // if tag == skipValidationTag { - // return - // } - - // if cTag == nil { - // var isCached bool - // cTag, isCached = v.oldTagCache.Get(tag) - - // if !isCached { - // cTag = v.parseTags(tag, name) - // } - // } - current, kind := v.ExtractType(current) var typ reflect.Type - // fmt.Println("TS:", ct, kind) - switch kind { case reflect.Ptr, reflect.Interface, reflect.Invalid: - // return - if ct == nil { return } @@ -669,7 +588,6 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect. return } - // if !ct.hasTag { if ct.hasTag { ns := errPrefix + cf.Name @@ -704,8 +622,6 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect. return } - // return - // if we get here tag length is zero and we can leave if kind == reflect.Invalid { return @@ -718,15 +634,12 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect. if ct != nil { ct = ct.next - // fmt.Println("CHECKING NO STRUCT LEVEL", ct.isNoStructLevel, ct.next) } - // if ct != nil && (ct.isNoStructLevel || (ct.next != nil && ct.next.isNoStructLevel)) { if ct != nil && ct.isNoStructLevel { return } - // func (v *Validate) tranverseStruct(topStruct reflect.Value, errPrefix string, nsPrefix string, errs ValidationErrors, useStructName bool, partial bool, exclude bool, includeExclude map[string]*struct{}, cs *cStruct, ct *cTag) v.tranverseStruct(topStruct, current, current, errPrefix+cf.Name+namespaceSeparator, nsPrefix+cf.AltName+namespaceSeparator, errs, false, partial, exclude, includeExclude, cs, ct) return } @@ -761,12 +674,8 @@ OUTER: if ct.isDive { - // fmt.Println("IN DIVE:", ct) - ct = ct.next - // fmt.Println("NEXT:", ct) - // traverse slice or map here // or panic ;) switch kind { @@ -775,14 +684,12 @@ OUTER: for i := 0; i < current.Len(); i++ { v.traverseField(topStruct, currentStruct, current.Index(i), errPrefix, nsPrefix, errs, partial, exclude, includeExclude, cs, &cField{Name: fmt.Sprintf(arrayIndexFieldName, cf.Name, i), AltName: fmt.Sprintf(arrayIndexFieldName, cf.AltName, i)}, ct) } - // v.traverseSlice(topStruct, currentStruct, current, errPrefix, nsPrefix, errs, diveSubTag, name, customName, partial, exclude, includeExclude, nil) + case reflect.Map: for _, key := range current.MapKeys() { v.traverseField(topStruct, currentStruct, current.MapIndex(key), errPrefix, nsPrefix, errs, partial, exclude, includeExclude, cs, &cField{Name: fmt.Sprintf(mapIndexFieldName, cf.Name, key.Interface()), AltName: fmt.Sprintf(mapIndexFieldName, cf.AltName, key.Interface())}, ct) - // v.traverseField(topStruct, currentStruct, current.MapIndex(key), errPrefix, nsPrefix, errs, false, tag, fmt.Sprintf(mapIndexFieldName, name, key.Interface()), fmt.Sprintf(mapIndexFieldName, customName, key.Interface()), partial, exclude, includeExclude, cTag) } - // v.traverseMap(topStruct, currentStruct, current, errPrefix, nsPrefix, errs, diveSubTag, name, customName, partial, exclude, includeExclude, nil) default: // throw error, if not a slice or map then should not have gotten here // bad dive tag @@ -796,44 +703,8 @@ OUTER: errTag := blank - // for _, val := range valTag.tagVals { for { - // fmt.Println(ct) - // if ct == nil { - // // if we get here, no valid 'or' value and no more tags - - // ns := errPrefix + cf.Name - - // if ct.hasAlias { - // errs[ns] = &FieldError{ - // FieldNamespace: ns, - // NameNamespace: nsPrefix + cf.AltName, - // Name: cf.AltName, - // Field: cf.Name, - // Tag: ct.aliasTag, - // ActualTag: ct.tag, - // Value: current.Interface(), - // Type: typ, - // Kind: kind, - // } - // } else { - // errs[errPrefix+cf.Name] = &FieldError{ - // FieldNamespace: ns, - // NameNamespace: nsPrefix + cf.AltName, - // Name: cf.AltName, - // Field: cf.Name, - // Tag: errTag[1:], - // ActualTag: errTag[1:], - // Value: current.Interface(), - // Type: typ, - // Kind: kind, - // } - // } - - // return - // } - if !ct.isOrVal { // if we get here, no valid 'or' value, but more tags @@ -866,15 +737,8 @@ OUTER: } continue OUTER - // break - // goto VAL } - // valFunc, ok = v.validationFuncs[val[0]] - // if !ok { - // panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, name))) - // } - if ct.fn(v, topStruct, currentStruct, current, typ, kind, ct.param) { // drain rest of the 'or' values, then continue or leave @@ -888,8 +752,6 @@ OUTER: if !ct.isOrVal { continue OUTER - // break - // goto VAL } } } @@ -932,46 +794,8 @@ OUTER: ct = ct.next } - // if valFunc(v, topStruct, currentStruct, current, currentType, currentKind, val[1]) { - // return false - // } - - // errTag += orSeparator + val[0] - // } - - // ns := errPrefix + name - - // if valTag.isAlias { - // errs[ns] = &FieldError{ - // FieldNamespace: ns, - // NameNamespace: nsPrefix + customName, - // Name: customName, - // Field: name, - // Tag: valTag.tag, - // ActualTag: errTag[1:], - // Value: current.Interface(), - // Type: currentType, - // Kind: currentKind, - // } - // } else { - // errs[errPrefix+name] = &FieldError{ - // FieldNamespace: ns, - // NameNamespace: nsPrefix + customName, - // Name: customName, - // Field: name, - // Tag: errTag[1:], - // ActualTag: errTag[1:], - // Value: current.Interface(), - // Type: currentType, - // Kind: currentKind, - // } - - // NOT SURE ABOUT THE BELOW LINE BEING COMMENT, LINT SAYS IT's Unreachable but.... - // return } - // fmt.Println(ct) - if !ct.fn(v, topStruct, currentStruct, current, typ, kind, ct.param) { ns := errPrefix + cf.Name @@ -992,176 +816,7 @@ OUTER: return } - // VAL: - // valFunc, ok = v.validationFuncs[valTag.tagVals[0][0]] - // if !ok { - // panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, name))) - // } - - // if valFunc(v, topStruct, currentStruct, current, currentType, currentKind, valTag.tagVals[0][1]) { - // return false - // } - - // ns := errPrefix + name - - // errs[ns] = &FieldError{ - // FieldNamespace: ns, - // NameNamespace: nsPrefix + customName, - // Name: customName, - // Field: name, - // Tag: valTag.tag, - // ActualTag: valTag.tagVals[0][0], - // Value: current.Interface(), - // Param: valTag.tagVals[0][1], - // Type: currentType, - // Kind: currentKind, - // } - - // if v.validateField(topStruct, currentStruct, current, typ, kind, errPrefix, nsPrefix, errs, valTag, name, customName) { - // return - // } ct = ct.next } - - // var dive bool - // var diveSubTag string - - // for _, valTag := range cTag.tags { - - // // if valTag.tagVals[0][0] == existsTag { - // // continue - // // } - - // // if valTag.tagVals[0][0] == diveTag { - // // dive = true - // // diveSubTag = strings.TrimLeft(strings.SplitN(cTag.diveTag, diveTag, 2)[1], ",") - // // break - // // } - - // // if valTag.tagVals[0][0] == omitempty { - - // // if !HasValue(v, topStruct, currentStruct, current, typ, kind, blank) { - // // return - // // } - // // continue - // // } - - // if v.validateField(topStruct, currentStruct, current, typ, kind, errPrefix, nsPrefix, errs, valTag, name, customName) { - // return - // } - // } - - // if dive { - // // traverse slice or map here - // // or panic ;) - // switch kind { - // case reflect.Slice, reflect.Array: - // v.traverseSlice(topStruct, currentStruct, current, errPrefix, nsPrefix, errs, diveSubTag, name, customName, partial, exclude, includeExclude, nil) - // case reflect.Map: - // v.traverseMap(topStruct, currentStruct, current, errPrefix, nsPrefix, errs, diveSubTag, name, customName, partial, exclude, includeExclude, nil) - // default: - // // throw error, if not a slice or map then should not have gotten here - // // bad dive tag - // panic("dive error! can't dive on a non slice or map") - // } - // } } - -// // traverseSlice traverses a Slice or Array's elements and passes them to traverseField for validation -// func (v *Validate) traverseSlice(topStruct reflect.Value, currentStruct reflect.Value, current reflect.Value, errPrefix string, nsPrefix string, errs ValidationErrors, tag, name, customName string, partial bool, exclude bool, includeExclude map[string]*struct{}, cTag *cachedTag) { - -// for i := 0; i < current.Len(); i++ { -// v.traverseField(topStruct, currentStruct, current.Index(i), errPrefix, nsPrefix, errs, false, tag, fmt.Sprintf(arrayIndexFieldName, name, i), fmt.Sprintf(arrayIndexFieldName, customName, i), partial, exclude, includeExclude, cTag) -// } -// } - -// // traverseMap traverses a map's elements and passes them to traverseField for validation -// func (v *Validate) traverseMap(topStruct reflect.Value, currentStruct reflect.Value, current reflect.Value, errPrefix string, nsPrefix string, errs ValidationErrors, tag, name, customName string, partial bool, exclude bool, includeExclude map[string]*struct{}, cTag *cachedTag) { - -// for _, key := range current.MapKeys() { -// v.traverseField(topStruct, currentStruct, current.MapIndex(key), errPrefix, nsPrefix, errs, false, tag, fmt.Sprintf(mapIndexFieldName, name, key.Interface()), fmt.Sprintf(mapIndexFieldName, customName, key.Interface()), partial, exclude, includeExclude, cTag) -// } -// } - -// // validateField validates a field based on the provided tag's key and param values and returns true if there is an error or false if all ok -// func (v *Validate) validateField(topStruct reflect.Value, currentStruct reflect.Value, current reflect.Value, currentType reflect.Type, currentKind reflect.Kind, errPrefix string, nsPrefix string, errs ValidationErrors, valTag *tagVals, name, customName string) bool { - -// var valFunc Func -// var ok bool - -// if valTag.isOrVal { - -// errTag := blank - -// for _, val := range valTag.tagVals { - -// valFunc, ok = v.validationFuncs[val[0]] -// if !ok { -// panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, name))) -// } - -// if valFunc(v, topStruct, currentStruct, current, currentType, currentKind, val[1]) { -// return false -// } - -// errTag += orSeparator + val[0] -// } - -// ns := errPrefix + name - -// if valTag.isAlias { -// errs[ns] = &FieldError{ -// FieldNamespace: ns, -// NameNamespace: nsPrefix + customName, -// Name: customName, -// Field: name, -// Tag: valTag.tag, -// ActualTag: errTag[1:], -// Value: current.Interface(), -// Type: currentType, -// Kind: currentKind, -// } -// } else { -// errs[errPrefix+name] = &FieldError{ -// FieldNamespace: ns, -// NameNamespace: nsPrefix + customName, -// Name: customName, -// Field: name, -// Tag: errTag[1:], -// ActualTag: errTag[1:], -// Value: current.Interface(), -// Type: currentType, -// Kind: currentKind, -// } -// } - -// return true -// } - -// valFunc, ok = v.validationFuncs[valTag.tagVals[0][0]] -// if !ok { -// panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, name))) -// } - -// if valFunc(v, topStruct, currentStruct, current, currentType, currentKind, valTag.tagVals[0][1]) { -// return false -// } - -// ns := errPrefix + name - -// errs[ns] = &FieldError{ -// FieldNamespace: ns, -// NameNamespace: nsPrefix + customName, -// Name: customName, -// Field: name, -// Tag: valTag.tag, -// ActualTag: valTag.tagVals[0][0], -// Value: current.Interface(), -// Param: valTag.tagVals[0][1], -// Type: currentType, -// Kind: currentKind, -// } - -// return true -// }