Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 21 additions & 123 deletions baked_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import (
"time"
)

// BakedInValidators is the map of ValidationFunc used internally
// but can be used with any new Validator if desired
// BakedInValidators is the default map of ValidationFunc
// you can add, remove or even replace items to suite your needs,
// or even disregard and use your own map if so desired.
var BakedInValidators = map[string]ValidationFunc{
"required": hasValue,
"len": hasLengthOf,
Expand Down Expand Up @@ -54,7 +55,6 @@ func isURI(top interface{}, current interface{}, field interface{}, param string
}

func isURL(top interface{}, current interface{}, field interface{}, param string) bool {

st := reflect.ValueOf(field)

switch st.Kind() {
Expand All @@ -77,146 +77,47 @@ func isURL(top interface{}, current interface{}, field interface{}, param string
}

func isEmail(top interface{}, current interface{}, field interface{}, param string) bool {

st := reflect.ValueOf(field)

switch st.Kind() {

case reflect.String:
return emailRegex.MatchString(field.(string))
}

panic(fmt.Sprintf("Bad field type %T", field))
return matchesRegex(emailRegex, field)
}

func isHsla(top interface{}, current interface{}, field interface{}, param string) bool {

st := reflect.ValueOf(field)

switch st.Kind() {

case reflect.String:
return hslaRegex.MatchString(field.(string))
}

panic(fmt.Sprintf("Bad field type %T", field))
return matchesRegex(hslaRegex, field)
}

func isHsl(top interface{}, current interface{}, field interface{}, param string) bool {

st := reflect.ValueOf(field)

switch st.Kind() {

case reflect.String:
return hslRegex.MatchString(field.(string))
}

panic(fmt.Sprintf("Bad field type %T", field))
return matchesRegex(hslRegex, field)
}

func isRgba(top interface{}, current interface{}, field interface{}, param string) bool {

st := reflect.ValueOf(field)

switch st.Kind() {

case reflect.String:
return rgbaRegex.MatchString(field.(string))
}

panic(fmt.Sprintf("Bad field type %T", field))
return matchesRegex(rgbaRegex, field)
}

func isRgb(top interface{}, current interface{}, field interface{}, param string) bool {

st := reflect.ValueOf(field)

switch st.Kind() {

case reflect.String:
return rgbRegex.MatchString(field.(string))
}

panic(fmt.Sprintf("Bad field type %T", field))
return matchesRegex(rgbRegex, field)
}

func isHexcolor(top interface{}, current interface{}, field interface{}, param string) bool {

st := reflect.ValueOf(field)

switch st.Kind() {

case reflect.String:
return hexcolorRegex.MatchString(field.(string))
}

panic(fmt.Sprintf("Bad field type %T", field))
return matchesRegex(hexcolorRegex, field)
}

func isHexadecimal(top interface{}, current interface{}, field interface{}, param string) bool {

st := reflect.ValueOf(field)

switch st.Kind() {

case reflect.String:
return hexadecimalRegex.MatchString(field.(string))
}

panic(fmt.Sprintf("Bad field type %T", field))
return matchesRegex(hexadecimalRegex, field)
}

func isNumber(top interface{}, current interface{}, field interface{}, param string) bool {

st := reflect.ValueOf(field)

switch st.Kind() {

case reflect.String:
return numberRegex.MatchString(field.(string))
}

panic(fmt.Sprintf("Bad field type %T", field))
return matchesRegex(numberRegex, field)
}

func isNumeric(top interface{}, current interface{}, field interface{}, param string) bool {

st := reflect.ValueOf(field)

switch st.Kind() {

case reflect.String:
return numericRegex.MatchString(field.(string))
}

panic(fmt.Sprintf("Bad field type %T", field))
return matchesRegex(numericRegex, field)
}

func isAlphanum(top interface{}, current interface{}, field interface{}, param string) bool {

st := reflect.ValueOf(field)

switch st.Kind() {

case reflect.String:
return alphaNumericRegex.MatchString(field.(string))
}

panic(fmt.Sprintf("Bad field type %T", field))
return matchesRegex(alphaNumericRegex, field)
}

func isAlpha(top interface{}, current interface{}, field interface{}, param string) bool {

st := reflect.ValueOf(field)

switch st.Kind() {

case reflect.String:
return alphaRegex.MatchString(field.(string))
}

panic(fmt.Sprintf("Bad field type %T", field))
return matchesRegex(alphaRegex, field)
}

func hasValue(top interface{}, current interface{}, field interface{}, param string) bool {
Expand Down Expand Up @@ -767,10 +668,7 @@ func hasMaxOf(top interface{}, current interface{}, field interface{}, param str
func asInt(param string) int64 {

i, err := strconv.ParseInt(param, 0, 64)

if err != nil {
panic(err.Error())
}
panicIf(err)

return i
}
Expand All @@ -780,10 +678,7 @@ func asInt(param string) int64 {
func asUint(param string) uint64 {

i, err := strconv.ParseUint(param, 0, 64)

if err != nil {
panic(err.Error())
}
panicIf(err)

return i
}
Expand All @@ -793,10 +688,13 @@ func asUint(param string) uint64 {
func asFloat(param string) float64 {

i, err := strconv.ParseFloat(param, 64)
panicIf(err)

return i
}

func panicIf(err error) {
if err != nil {
panic(err.Error())
}

return i
}
18 changes: 10 additions & 8 deletions doc.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
/*
Package validator implements value validations for structs and individual fields based on tags.
Package validator implements value validations for structs and individual fields based on tags. It can also handle Cross Field validation and even Cross Field Cross Struct validation for nested structs.

Built In Validator

v3 no longer contains a built in Validator instance.

myValidator = validator.NewValidator("validate", validator.BakedInValidators)

errs := myValidator.ValidateStruct(//your struct)
Expand Down Expand Up @@ -36,6 +34,9 @@ A simple example usage:
errs.StructErrors will be empty <-- fields that were structs
errs.Errors will have 1 error of type FieldValidationError

NOTE: Anonymous Structs - they don't have names so expect the Struct name
within StructValidationErrors to be blank.

Error Handling

The error can be used like so
Expand Down Expand Up @@ -103,9 +104,9 @@ Cross Field Validation can be implemented, for example Start & End Date range va
// when calling myValidator.ValidateFieldByTag(field, tag) val will be nil
//
// Because of the specific requirements and field names within each persons project that
// uses this library it is likely that custom functions will need to be created.
// however there are some build in Generic Cross Field validation, see Baked In Validators and
// Tags below
// uses this library it is likely that custom functions will need to be created for your
// Cross Field Validation needs, however there are some build in Generic Cross Field validations,
// see Baked In Validators and Tags below

func isDateRangeValid(val interface{}, field interface{}, param string) bool {

Expand Down Expand Up @@ -307,10 +308,11 @@ Validator notes:
a regex which conflict with the validation definitions, although workarounds
can be made, they take away from using pure regex's. Furthermore it's quick
and dirty but the regex's become harder to maintain and are not reusable, so
it's as much as a programming philosiphy as anything.
it's as much a programming philosiphy as anything.

In place of this new validator functions should be created; a regex can be
used within the validator function and even be precompiled for better efficiency.
used within the validator function and even be precompiled for better efficiency
within regexes.go.

And the best reason, you can sumit a pull request and we can keep on adding to the
validation library of this package!
Expand Down
7 changes: 5 additions & 2 deletions regexes.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ const (
hslRegexString = "^hsl\\(\\s*(0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*((0|[1-9]\\d?|100)%)\\s*,\\s*((0|[1-9]\\d?|100)%)\\s*\\)$"
hslaRegexString = "^hsla\\(\\s*(0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*((0|[1-9]\\d?|100)%)\\s*,\\s*((0|[1-9]\\d?|100)%)\\s*,\\s*((0.[1-9]*)|[01])\\s*\\)$"
emailRegexString = "^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$"
// urlRegexString = `^((ftp|http|https):\/\/)?(\S+(:\S*)?@)?((([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|((www\.)?)?(([a-z\x{00a1}-\x{ffff}0-9]+-?-?_?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-z\x{00a1}-\x{ffff}]{2,}))?)|localhost)(:(\d{1,5}))?((\/|\?|#)[^\s]*)?$`
// urlRegexString = "^(?:(?:https?|ftp):\\/\\/)(?:\\S+(?::\\S*)?@)?(?:(?!10(?:\\.\\d{1,3}){3})(?!127(?:\\.\\d{1,3}){3})(?!169\\.254(?:\\.\\d{1,3}){2})(?!192\\.168(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\\.(?:[a-z\u00a1-\uffff]{2,})))(?::\\d{2,5})?(?:\\/[^\\s]*)?$"
)

var (
Expand All @@ -31,3 +29,8 @@ var (
hslaRegex = regexp.MustCompile(hslaRegexString)
emailRegex = regexp.MustCompile(emailRegexString)
)

func matchesRegex(regex *regexp.Regexp, field interface{}) bool {
fieldAsString := field.(string) //this will panic inherently
return regex.MatchString(fieldAsString)
}
Loading