diff --git a/examples/custom.go b/examples/custom.go new file mode 100644 index 0000000..d7eb3b2 --- /dev/null +++ b/examples/custom.go @@ -0,0 +1,47 @@ +package main + +import ( + "database/sql" + "database/sql/driver" + "fmt" + "reflect" + + validator "gopkg.in/bluesuncorp/validator.v6" +) + +type DbBackedUser struct { + Name sql.NullString `validate:"required"` + Age sql.NullInt64 `validate:"required"` +} + +func main() { + + config := validator.Config{ + TagName: "validate", + ValidationFuncs: validator.BakedInValidators, + } + + validate := validator.New(config) + + // register all sql.Null* types to use the ValidateValuer CustomTypeFunc + validate.RegisterCustomTypeFunc(ValidateValuer, sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{}) + + x := DbBackedUser{Name: sql.NullString{String: "", Valid: true}, Age: sql.NullInt64{Int64: 0, Valid: false}} + errs := validate.Struct(x) + + if len(errs) > 0 { + fmt.Printf("Errs:\n%+v\n", errs) + } +} + +// ValidateValuer implements validator.CustomTypeFunc +func ValidateValuer(field reflect.Value) interface{} { + if valuer, ok := field.Interface().(driver.Valuer); ok { + val, err := valuer.Value() + if err == nil { + return val + } + // handle the error how you want + } + return nil +} diff --git a/validator.go b/validator.go index e557d28..9fb4dcf 100644 --- a/validator.go +++ b/validator.go @@ -157,6 +157,17 @@ func (v *Validate) RegisterValidation(key string, f Func) error { return nil } +// RegisterCustomTypeFunc registers types w/a custom type handler function. +func (v *Validate) RegisterCustomTypeFunc(f CustomTypeFunc, sampleTypeValues ...interface{}) { + if v.config.CustomTypeFuncs == nil { + v.config.CustomTypeFuncs = map[reflect.Type]CustomTypeFunc{} + } + for _, sample := range sampleTypeValues { + v.config.CustomTypeFuncs[reflect.TypeOf(sample)] = f + } + v.config.hasCustomFuncs = true +} + // Field validates a single field using tag style validation and returns ValidationErrors // NOTE: it returns ValidationErrors instead of a single FieldError because this can also // validate Array, Slice and maps fields which may contain more than one error