determined variable values to be passed

for #74
pull/114/head
joeybloggs 10 years ago
parent c62550c414
commit e42d7b683a
  1. 83
      validator.go
  2. 1
      validator_test.go

@ -8,6 +8,17 @@
package validator package validator
import (
"bytes"
"fmt"
"reflect"
"strings"
)
const (
fieldErrMsg = "Key: \"%s\" Error:Field validation for \"%s\" failed on the \"%s\" tag"
)
// Validate implements the Validate Struct // Validate implements the Validate Struct
// NOTE: Fields within are not thread safe and that is on purpose // NOTE: Fields within are not thread safe and that is on purpose
// Functions and Tags should all be predifined before use, so subscribe to the philosiphy // Functions and Tags should all be predifined before use, so subscribe to the philosiphy
@ -30,11 +41,31 @@ type Config struct {
// param = parameter used in validation i.e. gt=0 param would be 0 // param = parameter used in validation i.e. gt=0 param would be 0
type Func func(top interface{}, current interface{}, f interface{}, param string) bool type Func func(top interface{}, current interface{}, f interface{}, param string) bool
// ValidationErrors is a type of map[string]*FieldError
// it exists to allow for multiple errors passed from this library
// and yet still comply to the error interface
type ValidationErrors map[string]*FieldError
// This is intended for use in development + debugging and not intended to be a production error message.
// It allows ValidationErrors to subscribe to the Error interface.
// All information to create an error message specific to your application is contained within
// the FieldError found in the ValidationErrors
func (ve ValidationErrors) Error() string {
buff := bytes.NewBufferString("")
for key, err := range ve {
buff.WriteString(fmt.Sprintf(fieldErrMsg, key, err.Field, err.Tag))
}
return strings.TrimSpace(buff.String())
}
// FieldError contains a single field's validation error along // FieldError contains a single field's validation error along
// with other properties that may be needed for error message creation // with other properties that may be needed for error message creation
type FieldError struct { type FieldError struct {
Field string Field string
// Tag string Tag string
// Kind reflect.Kind // Kind reflect.Kind
// Type reflect.Type // Type reflect.Type
// Param string // Param string
@ -58,48 +89,36 @@ func New(config Config) *Validate {
// NOTE: Nested Arrays, or Maps of structs do not get validated only the Array or Map itself; the reason is that there is no good // NOTE: Nested Arrays, or Maps of structs do not get validated only the Array or Map itself; the reason is that there is no good
// way to represent or report which struct within the array has the error, besides can validate the struct prior to adding it to // way to represent or report which struct within the array has the error, besides can validate the struct prior to adding it to
// the Array or Map. // the Array or Map.
func (v *Validate) Struct(s interface{}) map[string]*FieldError { func (v *Validate) Struct(current interface{}) ValidationErrors {
// var err *FieldError
errs := map[string]*FieldError{} errs := map[string]*FieldError{}
// errchan := make(chan *FieldError) sv := reflect.ValueOf(current)
// done := make(chan bool)
// wg := &sync.WaitGroup{} v.structRecursive(sv, sv, "", errs)
v.structRecursive(s, s, s, 0, errs) if len(errs) == 0 {
return nil
// LOOP: }
// for {
// select {
// case err := <-errchan:
// errs[err.Field] = err
// // fmt.Println(err)
// case <-done:
// // fmt.Println("All Done")
// break LOOP
// }
// }
return errs return errs
} }
func (v *Validate) structRecursive(top interface{}, current interface{}, s interface{}, depth int, errs map[string]*FieldError) { // func (v *Validate) structRecursive(top interface{}, current interface{}, s interface{}, errs map[string]*FieldError) {
func (v *Validate) structRecursive(top reflect.Value, current reflect.Value, errPrefix string, errs ValidationErrors) {
errs["Name"] = &FieldError{Field: "Name"} if current.Kind() == reflect.Ptr && !current.IsNil() {
current = current.Elem()
}
if depth < 3 { if current.Kind() != reflect.Struct && current.Kind() != reflect.Interface {
// wg.Add(1) panic("value passed for validation is not a struct")
v.structRecursive(s, s, s, depth+1, errs)
} }
// wg.Wait() // errs[errPrefix+"Name"] = &FieldError{Field: "Name", Tag: "required"}
// if depth == 0 { // if depth < 3 {
// // wg.Wait() // v.structRecursive(top, current, errs)
// done <- true
// // return
// } else {
// // wg.Done()
// } // }
} }

@ -213,6 +213,7 @@ func TestValidation(t *testing.T) {
errs := validate.Struct(tst) errs := validate.Struct(tst)
fmt.Println(errs) fmt.Println(errs)
fmt.Println(errs == nil)
} }
// func AssertStruct(t *testing.T, s *StructErrors, structFieldName string, expectedStructName string) *StructErrors { // func AssertStruct(t *testing.T, s *StructErrors, structFieldName string, expectedStructName string) *StructErrors {

Loading…
Cancel
Save