Merge pull request #144 from joeybloggs/v6-development

Add exists tag
pull/146/head
Dean Karn 9 years ago
commit 3f5b785707
  1. 8
      doc.go
  2. 5
      validator.go
  3. 31
      validator_test.go

@ -102,6 +102,14 @@ Here is a list of the current built in validators:
you know the struct will be valid, but need to verify it has been assigned. you know the struct will be valid, but need to verify it has been assigned.
NOTE: only "required" and "omitempty" can be used on a struct itself. NOTE: only "required" and "omitempty" can be used on a struct itself.
exists
Is a special tag without a validation function attached. It is used when a field
is a Pointer, Interface or Invalid and you wish to validate that it exists.
Example: want to ensure a bool exists if you define the bool as a pointer and
use exists it will ensure there is a value; couldn't use required as it would
fail when the bool was false. exists will fail is the value is a Pointer, Interface
or Invalid and is nil. (Usage: exists)
omitempty omitempty
Allows conditional validation, for example if a field is not set with Allows conditional validation, for example if a field is not set with
a value (Determined by the "required" validator) then other validation a value (Determined by the "required" validator) then other validation

@ -29,6 +29,7 @@ const (
omitempty = "omitempty" omitempty = "omitempty"
skipValidationTag = "-" skipValidationTag = "-"
diveTag = "dive" diveTag = "dive"
existsTag = "exists"
fieldErrMsg = "Key: \"%s\" Error:Field validation for \"%s\" failed on the \"%s\" tag" fieldErrMsg = "Key: \"%s\" Error:Field validation for \"%s\" failed on the \"%s\" tag"
arrayIndexFieldName = "%s[%d]" arrayIndexFieldName = "%s[%d]"
mapIndexFieldName = "%s[%v]" mapIndexFieldName = "%s[%v]"
@ -418,6 +419,10 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect.
for _, cTag := range tags { for _, cTag := range tags {
if cTag.tagVals[0][0] == existsTag {
continue
}
if cTag.tagVals[0][0] == diveTag { if cTag.tagVals[0][0] == diveTag {
dive = true dive = true
diveSubTag = strings.TrimLeft(strings.SplitN(tag, diveTag, 2)[1], ",") diveSubTag = strings.TrimLeft(strings.SplitN(tag, diveTag, 2)[1], ",")

@ -3,6 +3,7 @@ package validator
import ( import (
"database/sql" "database/sql"
"database/sql/driver" "database/sql/driver"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"reflect" "reflect"
@ -191,6 +192,36 @@ func ValidateValuerType(field reflect.Value) interface{} {
return nil return nil
} }
func TestExistsValidation(t *testing.T) {
jsonText := "{ \"truthiness2\": true }"
type Thing struct {
Truthiness *bool `json:"truthiness" validate:"exists,required"`
}
var ting Thing
err := json.Unmarshal([]byte(jsonText), &ting)
Equal(t, err, nil)
NotEqual(t, ting, nil)
Equal(t, ting.Truthiness, nil)
errs := validate.Struct(ting)
NotEqual(t, errs, nil)
AssertError(t, errs, "Thing.Truthiness", "Truthiness", "exists")
jsonText = "{ \"truthiness\": true }"
err = json.Unmarshal([]byte(jsonText), &ting)
Equal(t, err, nil)
NotEqual(t, ting, nil)
Equal(t, ting.Truthiness, true)
errs = validate.Struct(ting)
Equal(t, errs, nil)
}
func TestSQLValue2Validation(t *testing.T) { func TestSQLValue2Validation(t *testing.T) {
config := Config{ config := Config{

Loading…
Cancel
Save