[Go] Package of validators and sanitizers for strings, numerics, slices and structs

govalidator

Gitter GoDoc Build Status Coverage Go Report Card GoSearch Backers on Open Collective Sponsors on Open Collective FOSSA Status

A package of validators and sanitizers for strings, structs and collections. Based on validator.js.

Installation

Make sure that Go is installed on your computer. Type the following command in your terminal:

go get github.com/asaskevich/govalidator

or you can get specified release of the package with gopkg.in:

go get gopkg.in/asaskevich/govalidator.v10

After it the package is ready to use.

Import package in your project

Add following line in your *.go file:

import "github.com/asaskevich/govalidator"

If you are unhappy to use long govalidator, you can do something like this:

import (
  valid "github.com/asaskevich/govalidator"
)

Activate behavior to require all fields have a validation tag by default

SetFieldsRequiredByDefault causes validation to fail when struct fields do not include validations or are not explicitly marked as exempt (using valid:"-" or valid:"email,optional"). A good place to activate this is a package init function or the main() function.

SetNilPtrAllowedByRequired causes validation to pass when struct fields marked by required are set to nil. This is disabled by default for consistency, but some packages that need to be able to determine between nil and zero value state can use this. If disabled, both nil and zero values cause validation errors.

import "github.com/asaskevich/govalidator"

func init() {
  govalidator.SetFieldsRequiredByDefault(true)
}

Here's some code to explain it:

// this struct definition will fail govalidator.ValidateStruct() (and the field values do not matter):
type exampleStruct struct {
  Name  string ``
  Email string `valid:"email"`
}

// this, however, will only fail when Email is empty or an invalid email address:
type exampleStruct2 struct {
  Name  string `valid:"-"`
  Email string `valid:"email"`
}

// lastly, this will only fail when Email is an invalid email address but not when it's empty:
type exampleStruct2 struct {
  Name  string `valid:"-"`
  Email string `valid:"email,optional"`
}

Recent breaking changes (see #123)

Custom validator function signature

A context was added as the second parameter, for structs this is the object being validated – this makes dependent validation possible.

import "github.com/asaskevich/govalidator"

// old signature
func(i interface{}) bool

// new signature
func(i interface{}, o interface{}) bool
Adding a custom validator

This was changed to prevent data races when accessing custom validators.

import "github.com/asaskevich/govalidator"

// before
govalidator.CustomTypeTagMap["customByteArrayValidator"] = func(i interface{}, o interface{}) bool {
  // ...
}

// after
govalidator.CustomTypeTagMap.Set("customByteArrayValidator", func(i interface{}, o interface{}) bool {
  // ...
})

List of functions:

func Abs(value float64) float64
func BlackList(str, chars string) string
func ByteLength(str string, params ...string) bool
func CamelCaseToUnderscore(str string) string
func Contains(str, substring string) bool
func Count(array []interface{}, iterator ConditionIterator) int
func Each(array []interface{}, iterator Iterator)
func ErrorByField(e error, field string) string
func ErrorsByField(e error) map[string]string
func Filter(array []interface{}, iterator ConditionIterator) []interface{}
func Find(array []interface{}, iterator ConditionIterator) interface{}
func GetLine(s string, index int) (string, error)
func GetLines(s string) []string
func HasLowerCase(str string) bool
func HasUpperCase(str string) bool
func HasWhitespace(str string) bool
func HasWhitespaceOnly(str string) bool
func InRange(value interface{}, left interface{}, right interface{}) bool
func InRangeFloat32(value, left, right float32) bool
func InRangeFloat64(value, left, right float64) bool
func InRangeInt(value, left, right interface{}) bool
func IsASCII(str string) bool
func IsAlpha(str string) bool
func IsAlphanumeric(str string) bool
func IsBase64(str string) bool
func IsByteLength(str string, min, max int) bool
func IsCIDR(str string) bool
func IsCRC32(str string) bool
func IsCRC32b(str string) bool
func IsCreditCard(str string) bool
func IsDNSName(str string) bool
func IsDataURI(str string) bool
func IsDialString(str string) bool
func IsDivisibleBy(str, num string) bool
func IsEmail(str string) bool
func IsExistingEmail(email string) bool
func IsFilePath(str string) (bool, int)
func IsFloat(str string) bool
func IsFullWidth(str string) bool
func IsHalfWidth(str string) bool
func IsHash(str string, algorithm string) bool
func IsHexadecimal(str string) bool
func IsHexcolor(str string) bool
func IsHost(str string) bool
func IsIP(str string) bool
func IsIPv4(str string) bool
func IsIPv6(str string) bool
func IsISBN(str string, version int) bool
func IsISBN10(str string) bool
func IsISBN13(str string) bool
func IsISO3166Alpha2(str string) bool
func IsISO3166Alpha3(str string) bool
func IsISO4217(str string) bool
func IsISO693Alpha2(str string) bool
func IsISO693Alpha3b(str string) bool
func IsIn(str string, params ...string) bool
func IsInRaw(str string, params ...string) bool
func IsInt(str string) bool
func IsJSON(str string) bool
func IsLatitude(str string) bool
func IsLongitude(str string) bool
func IsLowerCase(str string) bool
func IsMAC(str string) bool
func IsMD4(str string) bool
func IsMD5(str string) bool
func IsMagnetURI(str string) bool
func IsMongoID(str string) bool
func IsMultibyte(str string) bool
func IsNatural(value float64) bool
func IsNegative(value float64) bool
func IsNonNegative(value float64) bool
func IsNonPositive(value float64) bool
func IsNotNull(str string) bool
func IsNull(str string) bool
func IsNumeric(str string) bool
func IsPort(str string) bool
func IsPositive(value float64) bool
func IsPrintableASCII(str string) bool
func IsRFC3339(str string) bool
func IsRFC3339WithoutZone(str string) bool
func IsRGBcolor(str string) bool
func IsRequestURI(rawurl string) bool
func IsRequestURL(rawurl string) bool
func IsRipeMD128(str string) bool
func IsRipeMD160(str string) bool
func IsRsaPub(str string, params ...string) bool
func IsRsaPublicKey(str string, keylen int) bool
func IsSHA1(str string) bool
func IsSHA256(str string) bool
func IsSHA384(str string) bool
func IsSHA512(str string) bool
func IsSSN(str string) bool
func IsSemver(str string) bool
func IsTiger128(str string) bool
func IsTiger160(str string) bool
func IsTiger192(str string) bool
func IsTime(str string, format string) bool
func IsType(v interface{}, params ...string) bool
func IsURL(str string) bool
func IsUTFDigit(str string) bool
func IsUTFLetter(str string) bool
func IsUTFLetterNumeric(str string) bool
func IsUTFNumeric(str string) bool
func IsUUID(str string) bool
func IsUUIDv3(str string) bool
func IsUUIDv4(str string) bool
func IsUUIDv5(str string) bool
func IsUnixTime(str string) bool
func IsUpperCase(str string) bool
func IsVariableWidth(str string) bool
func IsWhole(value float64) bool
func LeftTrim(str, chars string) string
func Map(array []interface{}, iterator ResultIterator) []interface{}
func Matches(str, pattern string) bool
func MaxStringLength(str string, params ...string) bool
func MinStringLength(str string, params ...string) bool
func NormalizeEmail(str string) (string, error)
func PadBoth(str string, padStr string, padLen int) string
func PadLeft(str string, padStr string, padLen int) string
func PadRight(str string, padStr string, padLen int) string
func PrependPathToErrors(err error, path string) error
func Range(str string, params ...string) bool
func RemoveTags(s string) string
func ReplacePattern(str, pattern, replace string) string
func Reverse(s string) string
func RightTrim(str, chars string) string
func RuneLength(str string, params ...string) bool
func SafeFileName(str string) string
func SetFieldsRequiredByDefault(value bool)
func SetNilPtrAllowedByRequired(value bool)
func Sign(value float64) float64
func StringLength(str string, params ...string) bool
func StringMatches(s string, params ...string) bool
func StripLow(str string, keepNewLines bool) string
func ToBoolean(str string) (bool, error)
func ToFloat(str string) (float64, error)
func ToInt(value interface{}) (res int64, err error)
func ToJSON(obj interface{}) (string, error)
func ToString(obj interface{}) string
func Trim(str, chars string) string
func Truncate(str string, length int, ending string) string
func TruncatingErrorf(str string, args ...interface{}) error
func UnderscoreToCamelCase(s string) string
func ValidateMap(inputMap map[string]interface{}, validationMap map[string]interface{}) (bool, error)
func ValidateStruct(s interface{}) (bool, error)
func WhiteList(str, chars string) string
type ConditionIterator
type CustomTypeValidator
type Error
func (e Error) Error() string
type Errors
func (es Errors) Error() string
func (es Errors) Errors() []error
type ISO3166Entry
type ISO693Entry
type InterfaceParamValidator
type Iterator
type ParamValidator
type ResultIterator
type UnsupportedTypeError
func (e *UnsupportedTypeError) Error() string
type Validator

Examples

IsURL
println(govalidator.IsURL(`http://user@pass:domain.com/path/page`))
IsType
println(govalidator.IsType("Bob", "string"))
println(govalidator.IsType(1, "int"))
i := 1
println(govalidator.IsType(&i, "*int"))

IsType can be used through the tag type which is essential for map validation:

type User	struct {
  Name string      `valid:"type(string)"`
  Age  int         `valid:"type(int)"`
  Meta interface{} `valid:"type(string)"`
}
result, err := govalidator.ValidateStruct(User{"Bob", 20, "meta"})
if err != nil {
	println("error: " + err.Error())
}
println(result)
ToString
type User struct {
	FirstName string
	LastName string
}

str := govalidator.ToString(&User{"John", "Juan"})
println(str)
Each, Map, Filter, Count for slices

Each iterates over the slice/array and calls Iterator for every item

data := []interface{}{1, 2, 3, 4, 5}
var fn govalidator.Iterator = func(value interface{}, index int) {
	println(value.(int))
}
govalidator.Each(data, fn)
data := []interface{}{1, 2, 3, 4, 5}
var fn govalidator.ResultIterator = func(value interface{}, index int) interface{} {
	return value.(int) * 3
}
_ = govalidator.Map(data, fn) // result = []interface{}{1, 6, 9, 12, 15}
data := []interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
var fn govalidator.ConditionIterator = func(value interface{}, index int) bool {
	return value.(int)%2 == 0
}
_ = govalidator.Filter(data, fn) // result = []interface{}{2, 4, 6, 8, 10}
_ = govalidator.Count(data, fn) // result = 5
ValidateStruct #2

If you want to validate structs, you can use tag valid for any field in your structure. All validators used with this field in one tag are separated by comma. If you want to skip validation, place - in your tag. If you need a validator that is not on the list below, you can add it like this:

govalidator.TagMap["duck"] = govalidator.Validator(func(str string) bool {
	return str == "duck"
})

For completely custom validators (interface-based), see below.

Here is a list of available validators for struct fields (validator - used function):

"email":              IsEmail,
"url":                IsURL,
"dialstring":         IsDialString,
"requrl":             IsRequestURL,
"requri":             IsRequestURI,
"alpha":              IsAlpha,
"utfletter":          IsUTFLetter,
"alphanum":           IsAlphanumeric,
"utfletternum":       IsUTFLetterNumeric,
"numeric":            IsNumeric,
"utfnumeric":         IsUTFNumeric,
"utfdigit":           IsUTFDigit,
"hexadecimal":        IsHexadecimal,
"hexcolor":           IsHexcolor,
"rgbcolor":           IsRGBcolor,
"lowercase":          IsLowerCase,
"uppercase":          IsUpperCase,
"int":                IsInt,
"float":              IsFloat,
"null":               IsNull,
"uuid":               IsUUID,
"uuidv3":             IsUUIDv3,
"uuidv4":             IsUUIDv4,
"uuidv5":             IsUUIDv5,
"creditcard":         IsCreditCard,
"isbn10":             IsISBN10,
"isbn13":             IsISBN13,
"json":               IsJSON,
"multibyte":          IsMultibyte,
"ascii":              IsASCII,
"printableascii":     IsPrintableASCII,
"fullwidth":          IsFullWidth,
"halfwidth":          IsHalfWidth,
"variablewidth":      IsVariableWidth,
"base64":             IsBase64,
"datauri":            IsDataURI,
"ip":                 IsIP,
"port":               IsPort,
"ipv4":               IsIPv4,
"ipv6":               IsIPv6,
"dns":                IsDNSName,
"host":               IsHost,
"mac":                IsMAC,
"latitude":           IsLatitude,
"longitude":          IsLongitude,
"ssn":                IsSSN,
"semver":             IsSemver,
"rfc3339":            IsRFC3339,
"rfc3339WithoutZone": IsRFC3339WithoutZone,
"ISO3166Alpha2":      IsISO3166Alpha2,
"ISO3166Alpha3":      IsISO3166Alpha3,

Validators with parameters

"range(min|max)": Range,
"length(min|max)": ByteLength,
"runelength(min|max)": RuneLength,
"stringlength(min|max)": StringLength,
"matches(pattern)": StringMatches,
"in(string1|string2|...|stringN)": IsIn,
"rsapub(keylength)" : IsRsaPub,
"minstringlength(int): MinStringLength,
"maxstringlength(int): MaxStringLength,

Validators with parameters for any type

"type(type)": IsType,

And here is small example of usage:

type Post struct {
	Title    string `valid:"alphanum,required"`
	Message  string `valid:"duck,ascii"`
	Message2 string `valid:"animal(dog)"`
	AuthorIP string `valid:"ipv4"`
	Date     string `valid:"-"`
}
post := &Post{
	Title:   "My Example Post",
	Message: "duck",
	Message2: "dog",
	AuthorIP: "123.234.54.3",
}

// Add your own struct validation tags
govalidator.TagMap["duck"] = govalidator.Validator(func(str string) bool {
	return str == "duck"
})

// Add your own struct validation tags with parameter
govalidator.ParamTagMap["animal"] = govalidator.ParamValidator(func(str string, params ...string) bool {
    species := params[0]
    return str == species
})
govalidator.ParamTagRegexMap["animal"] = regexp.MustCompile("^animal\\((\\w+)\\)$")

result, err := govalidator.ValidateStruct(post)
if err != nil {
	println("error: " + err.Error())
}
println(result)
ValidateMap #2

If you want to validate maps, you can use the map to be validated and a validation map that contain the same tags used in ValidateStruct, both maps have to be in the form map[string]interface{}

So here is small example of usage:

var mapTemplate = map[string]interface{}{
	"name":"required,alpha",
	"family":"required,alpha",
	"email":"required,email",
	"cell-phone":"numeric",
	"address":map[string]interface{}{
		"line1":"required,alphanum",
		"line2":"alphanum",
		"postal-code":"numeric",
	},
}

var inputMap = map[string]interface{}{
	"name":"Bob",
	"family":"Smith",
	"email":"[email protected]",
	"address":map[string]interface{}{
		"line1":"",
		"line2":"",
		"postal-code":"",
	},
}

result, err := govalidator.ValidateMap(inputMap, mapTemplate)
if err != nil {
	println("error: " + err.Error())
}
println(result)
WhiteList
// Remove all characters from string ignoring characters between "a" and "z"
println(govalidator.WhiteList("a3a43a5a4a3a2a23a4a5a4a3a4", "a-z") == "aaaaaaaaaaaa")
Custom validation functions

Custom validation using your own domain specific validators is also available - here's an example of how to use it:

import "github.com/asaskevich/govalidator"

type CustomByteArray [6]byte // custom types are supported and can be validated

type StructWithCustomByteArray struct {
  ID              CustomByteArray `valid:"customByteArrayValidator,customMinLengthValidator"` // multiple custom validators are possible as well and will be evaluated in sequence
  Email           string          `valid:"email"`
  CustomMinLength int             `valid:"-"`
}

govalidator.CustomTypeTagMap.Set("customByteArrayValidator", func(i interface{}, context interface{}) bool {
  switch v := context.(type) { // you can type switch on the context interface being validated
  case StructWithCustomByteArray:
    // you can check and validate against some other field in the context,
    // return early or not validate against the context at all – your choice
  case SomeOtherType:
    // ...
  default:
    // expecting some other type? Throw/panic here or continue
  }

  switch v := i.(type) { // type switch on the struct field being validated
  case CustomByteArray:
    for _, e := range v { // this validator checks that the byte array is not empty, i.e. not all zeroes
      if e != 0 {
        return true
      }
    }
  }
  return false
})
govalidator.CustomTypeTagMap.Set("customMinLengthValidator", func(i interface{}, context interface{}) bool {
  switch v := context.(type) { // this validates a field against the value in another field, i.e. dependent validation
  case StructWithCustomByteArray:
    return len(v.ID) >= v.CustomMinLength
  }
  return false
})
Loop over Error()

By default .Error() returns all errors in a single String. To access each error you can do this:

  if err != nil {
    errs := err.(govalidator.Errors).Errors()
    for _, e := range errs {
      fmt.Println(e.Error())
    }
  }
Custom error messages

Custom error messages are supported via annotations by adding the ~ separator - here's an example of how to use it:

type Ticket struct {
  Id        int64     `json:"id"`
  FirstName string    `json:"firstname" valid:"required~First name is blank"`
}

Notes

Documentation is available here: godoc.org. Full information about code coverage is also available here: govalidator on gocover.io.

Support

If you do have a contribution to the package, feel free to create a Pull Request or an Issue.

What to contribute

If you don't know what to do, there are some features and functions that need to be done

  • Refactor code
  • Edit docs and README: spellcheck, grammar and typo check
  • Create actual list of contributors and projects that currently using this package
  • Resolve issues and bugs
  • Update actual list of functions
  • Update list of validators that available for ValidateStruct and add new
  • Implement new validators: IsFQDN, IsIMEI, IsPostalCode, IsISIN, IsISRC etc
  • Implement validation by maps
  • Implement fuzzing testing
  • Implement some struct/map/array utilities
  • Implement map/array validation
  • Implement benchmarking
  • Implement batch of examples
  • Look at forks for new features and fixes

Advice

Feel free to create what you want, but keep in mind when you implement new features:

  • Code must be clear and readable, names of variables/constants clearly describes what they are doing
  • Public functions must be documented and described in source file and added to README.md to the list of available functions
  • There are must be unit-tests for any new functions and improvements

Credits

Contributors

This project exists thanks to all the people who contribute. [Contribute].

Special thanks to contributors

Backers

Thank you to all our backers! 🙏 [Become a backer]

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

License

FOSSA Status

Comments
  • lessEqual(value), moreEqual(value), equal(value), notEqual(value) Options on structs

    lessEqual(value), moreEqual(value), equal(value), notEqual(value) Options on structs

    Currently there are validator functions like IsInt, but sometime it could be even more helpful to restrict the values further with a min or/and a max value. I'd really like to extend.the functionality so that such checks could be done.

    But as of now, I'm not that sure which approach would be the best, therefor I'd like to hear everyones opinion first. I'm open for other ideas or other approaches! This "issue" should be about how to solves this "feature request" the best!

    As my idea goes I would like to introduce 4 new options: lessequal(value), moreequal(value), equal(value), notequal(value). I chose those options as every "validator" is in conjunction with each other. Therefor we can't say less(value) and equal(value) to get lessequal(value), because if "a < b" is true "a = b" can't be true, therefore the validation would always return false.

    the usage would then look like this

    type Foobar struct {
        number1 string `valid:"int,lessequal(5),moreequal(-10),notequal(0)"` //means -10 <= number1 <= 5 && number1 != 0
        cons6 string `valid:"int,equal(6)"` //means cons6 == 6
        number2 string `valid:"int,lessequal(5),notequal(5)"` //means number2 < 5
        name string `valid:"ascii,noequal(admin)"` //means every (ascii) name beside 'admin' is valid
        uuid string `valid:"uuid, moreequal(A0000000-0000-0000-0000-000000000000)"`
    }
    

    we could even add some more options like range(min,max), but at first I'd like to concentrate on the 4 options I mentioned. If this 4 are done right, adding more should be quite easy (especially options like range(min,max))

    Now about how my current approach would look like respectively how I would implement this:

    First of all I would define a basic Validator struct which would be more or less the foundation of most (maybe all) validators.

    //Basic Validator
    type basicValidatorType struct {
        less  func(v1, v2 interface{}) bool
        more  func(v1, v2 interface{}) bool
        equal func(v1, v2 interface{}) bool
    }
    
    func (b basicValidatorType) isLessEqual(value, referenceValue string) bool {
        v, errV := b.convert(value)
        r, errR := b.convert(referenceValue)
        if errV != nil || errR != nil {
            return false
        }
        if b.equal != nil && b.equal(v, r) {
            return true
        }
        if b.equal == nil && reflect.DeepEqual(v, r) {
            return true
        }
        if b.less != nil && b.less(v, r) {
            return true
        }
        return false
    }
    func (b basicValidatorType) isMoreEqual(value, referenceValue string) bool {
        v, errV := b.convert(value)
        r, errR := b.convert(referenceValue)
        if errV != nil || errR != nil {
            return false
        }
        if b.equal != nil && b.equal(v, r) {
            return true
        }
        if b.equal == nil && reflect.DeepEqual(v, r) {
            return true
        }
        if b.more != nil && b.more(v, r) {
            return true
        }
        return false
    }
    func (b basicValidatorType) isEqual(value, referenceValue string) bool {
        v, errV := b.convert(value)
        r, errR := b.convert(referenceValue)
        if errV != nil || errR != nil {
            return false
        }
        if b.equal == nil {
            return reflect.DeepEqual(v, r)
        }
        return b.equal(v, r)
    }
    func (b basicValidatorType) isNotEqual(value, referenceValue string) bool {
        v, errV := b.convert(value)
        r, errR := b.convert(referenceValue)
        if errV != nil || errR != nil {
            return false
        }
        if b.equal == nil {
            return !reflect.DeepEqual(v, r)
        }
        return !b.equal(v, r)
    }
    func (b basicValidatorType) convert(value string) (interface{}, error) {
        return value, nil
    }
    

    The validators then would look like this (here an example of how IsInt would look like)

    //ValidatorType for IsInt
    type validatorInt basicValidatorType
    
    func (v validatorInt) convert(value string) (interface{}, error) {
        valueInt, err := strconv.ParseInt(value, 10, 64)
        return valueInt, err
    }
    
    var intValidator = validatorInt{
        //less
        func(v1, v2 interface{}) bool {
            int1, ok1 := v1.(int64)
            int2, ok2 := v2.(int64)
            if ok1 != true || ok2 != true {
                return false
            }
            return int1 < int2
        },
        //more
        func(v1, v2 interface{}) bool {
            int1, ok1 := v1.(int64)
            int2, ok2 := v2.(int64)
            if ok1 != true || ok2 != true {
                return false
            }
            return int1 > int2
        },
        //equal
        func(v1, v2 interface{}) bool {
            int1, ok1 := v1.(int64)
            int2, ok2 := v2.(int64)
            if ok1 != true || ok2 != true {
                return false
            }
            return int1 == int2
        },
    }
    
    func IsInt(str string) bool {
        _, err := intValidator.convert(str)
        return err == nil
    }
    

    To do all this I would need (IMO) to rebuild the whole validation process as shown in my example of IsInt. Rebuilden the whole code is something I'd like to avoid, therefor the questions are, if anyone has a better solution/approach or some ideas how to reduce code or the need to change code with my idea?

    Things I currently don't like on my idea but haven't found better solutions:

    1. To much heap allocations (e.g var intValidator)
  • Validate empty values

    Validate empty values

    Currently govalidator skips validation of zero numbers, empty strings, and other zero values of any type. It treats them as always valid. On the other hand, govalidator errs when a 'required' field has a zero value which disallows entering zero values into required fields.

    The goal of this PR is to solve both problems: to validate zero values and to allow 'required' fields to have zero/empty values.

    The main idea is to skip validation only when we are sure that a value is a nil-value (we can distinguish nil values from zero/empty values only for pointers, interfaces, maps, and slices; we consider all other values as non-nil values). All non-nil values are being validated. The 'required` validator errs only for nil values.

    If one wants to check that some required string or number is given, he/she can declare them as pointers:

    type MyStruct struct {
       Name     *string `valid:"required"`
       Number *int       `valid:"required"`
    }
    

    This will fail when Name and/or Number are not given or equal to nil.

    When one wants to disallow empty strings, it's still possible to use the runelength validator. And there is also the range validator for numeric values.

    This PR fixes #276, #274, (probably) #260, #256, #246, (probably) #149, (probably) #136, #130.

  • Validating struct inside struct where the kind of nested struct field is a pointer

    Validating struct inside struct where the kind of nested struct field is a pointer

    If the nested struct kind is a pointer/slice, it is not caught at validator.go:580

    		if valueField.Kind() == reflect.Struct {
    			var err error
    			structResult, err = ValidateStruct(valueField.Interface())
    			if err != nil {
    				errs = append(errs, err)
    			}
    		}
    

    Is that intentionally left out? If not, it would be awesome if that feature could be added.

  • how to return message with multile languages ?

    how to return message with multile languages ?

    the scenes is that I hav many languages that will return for validate failed . such as :

    
    type exampleStruct struct {
      Name  string ``
      Email string `valid:"email"`  //    email is not correct || email 格式错误 
    }
    
    

    how can I defined it .

  • How to validated boolean value?

    How to validated boolean value?

    type Request struct { Active bool json:"active" valid:"required~Status should not be blank" }

    When active variable have value "false" its always invalidate.

  • Fix validator processing errors

    Fix validator processing errors

    The following bugs have been fixed:

    • ValidateStruct() didn't return an error if an invalid validator was specified in the struct validation tags.
    • Built-in validators weren't processed when a custom validator was specified.

    This commit adds a check which ensures that the value is checked against all specified validators before return that the value is valid.


    This change is Reviewable

  • IsUTFDigit accepting some Strings it (IMO) shouldn't

    IsUTFDigit accepting some Strings it (IMO) shouldn't

    The IsUTFDigit accepts strings which contains non valid Digit character or aren't even valid numbers.

    IsUTFDigit accepts: "-1" "1-1" "-" "--------1" "1---" IsUTFDigits rejects: "+1" "1+1" "+" "+++++++1" "1+++"

    The question here is, what is the intended reaction of the IsUTFDigit function.

  • (Enhancement) Validator: Adding more concrete base64 validation, Enabling []int validation

    (Enhancement) Validator: Adding more concrete base64 validation, Enabling []int validation

    The current base64 validator makes a few assumptions about the nature of the base 64 string as a result of using regex. By using Go's build in base64 lib we circumvent the regex as well as adding full functionally to validate both standard base64 strings and raw base64 strings. This is an additive string, which allows for full backwards capabilities.

    (Enhancement) Validator: Validating contents of []int … Adding a new type to enable the ability to validate what's inside of an int slice. This is important for structured API documentation, when the items in the slice should be known integers. I didn't implement the other slice types as I don't have a use case for them, but it should be easy enough to extend. This is not a breaking change.

  • _ in URL makes them invalid

    _ in URL makes them invalid

    See https://github.com/prometheus/prometheus/issues/2717

    From that issue: RFC 952 says that:

    1. A "name" (Net, Host, Gateway, or Domain name) is a text string up
       to 24 characters drawn from the alphabet (A-Z), digits (0-9), minus
       sign (-), and period (.)
    

    But the rule apparently isn't strictly followed by DNS servers and names in an /etc/hosts file can contain underscores.

    Do you have any plans to support _?

  • Interplay between custom validators and optional fields

    Interplay between custom validators and optional fields

    As far as I understand and can surmise from the code, optional,required annotations are ignored when custom validators are defined on the same field.

    For instance, if I have defined a custom validator called version which allows for regex XX.XX.XXX on this field

        Version  string `json:"version" valid:"optional,version"`
    

    I expect when I am validating my struct as

        _, err = govalidator.ValidateStruct(<struct>)
    

    empty string will be allowed, but it is not!

    I wonder why the design decision was made this way?

    It is most inconvenient and requires users to always handle the empty field case explicitly. It is confusing that the validator which is a part of a standard library

        Email  string `json:"email" valid:"optional,email"`
    

    will work correctly with empty string, but a custom validator

        Version  string `json:"version" valid:"optional,version"`
    

    does not!

  • Change struct validator's separator between validators from

    Change struct validator's separator between validators from "," to "\n"

    Hi,

    This change started with the issue that trying to use struct validation using valid:matches(^.{3,}$),required to match any string with at least three characters, the problem is that it includes a comma in the expression.

    In this case, the tagParser() breaks this down as:

    • matches(^.{3
    • }$)
    • required

    Furthermore, since the first two expressions are not recognized, they are ignored silently, and you have to be careful your validations are not being ignored.

    The solution proposed is to change the "," as separator and turn the above struct validation valid:matches(^{.3,}$)\nrequired; The \n character is seldom used in regular expressions matching a single line wo it looks like a better choice, although not standard. The other option is to write a parser that takes this issue into account but would take more time I don't really have at this time.

    Please comment on what you guys think.

    Great piece of code, by the way!

    Regards,

    GM


    This change is Reviewable

  • fatal error: concurrent map writes

    fatal error: concurrent map writes

    The gin framework I use will cause fatal errors when there are too many concurrent accesses.

    fatal error: concurrent map writes

    
    // implements the binding.StructValidator
    type customValidator struct{}
    
    func (c *customValidator) ValidateStruct(ptr interface{}) error {
    
    	govalidator.ParamTagMap["google"] = govalidator.ParamValidator(func(str string, params ...string) bool {
    		a.Log.Debug("customGoogle ParamTagMap")
    		return false
    	})
    	govalidator.ParamTagMap["google"] = govalidator.ParamValidator(func(str string, params ...string) bool {
    		a.Log.Debug("customGoogle ParamTagMap")
    		return false
    	})
    
    	// Add your own struct validation tags with parameter
    	govalidator.ParamTagMap["compared"] = govalidator.ParamValidator(func(str string, params ...string) bool {
    		res := reflect.ValueOf(ptr).Elem().FieldByName(params[0]).Interface().(string)
    		return str == res
    	})
    
    	//register the regex for validate
    	govalidator.ParamTagRegexMap["compared"] = regexp.MustCompile("^compared\\((\\w+)\\)$")
    	if _, err := govalidator.ValidateStruct(ptr); err != nil {
    		a.Log.Errorf("ValidateStruct err:%v", err)
    		return err
    	}
    	return nil
    }
    
    func (c *customValidator) Engine() interface{} {
    	return nil
    }
    
    func main(){
    	binding.Validator = &customValidator{}
            r := gin.Default()
    	r.Run(":9191")
    }
    
  • Added IsE164 validation for struct fields

    Added IsE164 validation for struct fields

    | Q | A |---------------- | ------ | Documentation | no | Bugfix | no | BC Break | no | New Feature | yes | RFC | no | QA | no

    Description

    Added IsE164 validation for struct fields

  • add IsPrivateIP

    add IsPrivateIP

    | Q | A |-------------- | ------ | Documentation | yes | Bugfix | no | BC Break | no | New Feature | yes | RFC | yes | QA | yes

    Description

    add IsPrivateIP test ip is private ip

  • Is this project abandoned? Is there an active fork of this repo?

    Is this project abandoned? Is there an active fork of this repo?

    This is the second highest starred validation package in Go, but it appears there is no maintainer or activity on this repo.

    I would use go-playground/validator (the highest starred validation package I could find), however it's not suitable for my use-case as I cannot define custom errors per field, whereas asaskevich/govalidator does support this.

    Is there an active fork of this repo?

  • Do not put any limit on maximum URL length

    Do not put any limit on maximum URL length

    Limitation : Current implementation of IsURL function simply returns false (URL as invalid) if length of URL is more than 2082 runes/characters. It does not check if the URL is valid based on regex and URL-parsing.

    Approach Remove the if-check present on maximum length and allow the function to check if the URL is valid based on regex and URL-parsing.

Data validators for Golang

golidators Golidators is a golang package, it includes basic data validation functions and regexes. Install go get github.com/eredotpkfr/golidators Ov

Oct 19, 2022
Dec 28, 2022
Go package containing implementations of efficient encoding, decoding, and validation APIs.

encoding Go package containing implementations of encoders and decoders for various data formats. Motivation At Segment, we do a lot of marshaling and

Dec 25, 2022
This package provides a framework for writing validations for Go applications.

github.com/gobuffalo/validate This package provides a framework for writing validations for Go applications. It does provide you with few validators,

Dec 15, 2022
Library providing opanapi3 and Go types for store/validation and transfer of ISO-4217, ISO-3166, and other types.

go-types This library has been created with the purpose to facilitate the store, validation, and transfer of Go ISO-3166/ISO-4217/timezones/emails/URL

Nov 9, 2022
:100:Go Struct and Field validation, including Cross Field, Cross Struct, Map, Slice and Array diving

Package validator Package validator implements value validations for structs and individual fields based on tags. It has the following unique features

Jan 1, 2023
Provide check digit algorithms and calculators written in Go

checkdigit About Provide check digit algorithms and calculators written by Go. Provided methods Algorithms Luhn Verhoeff Damm Calculators ISBN-10 ISBN

Dec 17, 2022
A norms and conventions validator for Terraform

This tool will help you ensure that a terraform folder answer to your norms and conventions rules. This can be really useful in several cases : You're

Nov 29, 2022
Swagger builder and input validation for Go servers
Swagger builder and input validation for Go servers

crud A Swagger/OpenAPI builder and validation library for building HTTP/REST APIs. Heavily inspired by hapi and the hapi-swagger projects. No addition

Jan 5, 2023
Golang parameter validation, which can replace go-playground/validator, includes ncluding Cross Field, Map, Slice and Array diving, provides readable,flexible, configurable validation.
Golang parameter validation, which can replace go-playground/validator, includes ncluding Cross Field, Map, Slice and Array diving, provides readable,flexible, configurable validation.

Checker 中文版本 Checker is a parameter validation package, can be use in struct/non-struct validation, including cross field validation in struct, elemen

Dec 16, 2022
The Hyperscale InputFilter library provides a simple inputfilter chaining mechanism by which multiple filters and validator may be applied to a single datum in a user-defined order.

Hyperscale InputFilter Branch Status Coverage master The Hyperscale InputFilter library provides a simple inputfilter chaining mechanism by which mult

Oct 20, 2021
[Go] Package of validators and sanitizers for strings, numerics, slices and structs

govalidator A package of validators and sanitizers for strings, structs and collections. Based on validator.js. Installation Make sure that Go is inst

Dec 28, 2022
Scan database/sql rows directly to structs, slices, and primitive types

Scan Scan standard lib database rows directly to structs or slices. For the most comprehensive and up-to-date docs see the godoc Examples Multiple Row

Dec 28, 2022
Tutorial code for my video Learn to Use Basic Data Structures - Slices, Structs and Maps in Golang

Learn to Use Basic Data Structures - Slices, Structs and Maps in Golang Read text from a file and split into words. Introduction to slices / lists. Co

Jan 26, 2022
An idiomatic Go (golang) validation package. Supports configurable and extensible validation rules (validators) using normal language constructs instead of error-prone struct tags.

ozzo-validation Description ozzo-validation is a Go package that provides configurable and extensible data validation capabilities. It has the followi

Jan 7, 2023
A program to create assembly 8086 strings to print without using any printing/strings related function but only mov-xchg-int and loops

Assembly String builder tool A program to create assembly 8086 strings to print without using any printing/strings related function but only mov-xchg-

Feb 1, 2022
[UNMANTEINED] Extract values from strings and fill your structs with nlp.

nlp nlp is a general purpose any-lang Natural Language Processor that parses the data inside a text and returns a filled model Supported types int in

Nov 24, 2022
go-querystring is Go library for encoding structs into URL query strings.

go-querystring go-querystring is a Go library for encoding structs into URL query parameters. Usage import "github.com/google/go-querystring/query" go

Jan 9, 2023
K8s-go-structs - All k8s API Go structs

k8s-api go types Why? Its nice to have it all in a single package. . |-- pkg |

Jul 17, 2022
Schematic - Generates model and validators by schema definition

schematic Generates model and validators by schema definition. Install Warning:

Feb 10, 2022