Categorygithub.com/interactive-solutions/govalidator
modulepackage
0.0.0-20200930093759-d4bb53ede080
Repository: https://github.com/interactive-solutions/govalidator.git
Documentation: pkg.go.dev

# README

govalidator

Fork of govalidator.

Extends the original library by adding a context.Context parameter to all validator signatures, allowing us to pass custom parameters (parameters not part of the request) to a validator. Also added so validators can return errors because internal errors should not be hidden by a validation error.

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/interactive-solutions/govalidator

After it the package is ready to use.

Import package in your project

Add following line in your *.go file:

import "github.com/interactive-solutions/govalidator"

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

import (
  valid "github.com/interactive-solutions/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.

import "github.com/interactive-solutions/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"`
}

Breaking changes against original repository

Validator function signature

A context specified by the user was added as the first parameter.

import "github.com/interactive-solutions/govalidator"

// old signature
func(value string) bool

// new signature
func(ctx context.Context, value string) (bool, error)
Custom validator function signature

A context specified by the user was added as the first parameter.

import "github.com/interactive-solutions/govalidator"

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

// new signature
func(ctx context.Context, i, o interface{}) (bool, error)

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 InRange(value, left, right float64) 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 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 IsFilePath(str string) (bool, int)
func IsFloat(str string) bool
func IsFullWidth(str string) bool
func IsHalfWidth(str 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 IsISO693Alpha2(str string) bool
func IsISO693Alpha3b(str string) bool
func IsISO4217(str string) bool
func IsIn(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 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 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 IsSSN(str string) bool
func IsSemver(str string) bool
func IsTime(str string, format 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 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 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 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 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(str string) (int64, 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 UnderscoreToCamelCase(s string) string
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 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`))
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

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(ctx context.Context, str string) (bool, error) {
        duck, _ := ctx.Value("duck").(string)

        if duck == "duck" {
		return false, errors.New("Internal server error")
	}

	return str == duck, nil
})

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,
"matches(pattern)": StringMatches,
"in(string1|string2|...|stringN)": IsIn,

And here is small example of usage:

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

// Add your own struct validation tags
govalidator.TagMap["duck"] = govalidator.Validator(func(ctx context.Context, str string) (bool, error) {
	duck, _ := ctx.Value("duck").(string)

        if duck == "duck" {
		return false, errors.New("Internal server error")
	}

	return str == duck, nil
})

result, err := govalidator.ValidateStruct(post)
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/interactive-solutions/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", CustomTypeValidator(func(ctx context.Context, i, context interface{}) (bool, error) {
  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, nil
      }
    }
  }
  return false, nil
}))
govalidator.CustomTypeTagMap.Set("customMinLengthValidator", CustomTypeValidator(func(ctx context.Context, i, context interface{}) (bool, error) {
  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, nil
  }
  return false, nil
}))
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.

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

Special thanks to contributors

# Functions

Abs returns absolute value of number.
BlackList remove characters that appear in the blacklist.
ByteLength check string's length.
CamelCaseToUnderscore converts from camel case form to underscore separated form.
Contains check if the string contains the substring.
Count iterates over the slice and apply ConditionIterator to every item.
Each iterates over the slice and apply Iterator to every item.
ErrorByField returns error for specified field of the struct validated by ValidateStruct or empty string if there are no errors or this field doesn't exists or doesn't have any errors.
ErrorsByField returns map of errors of the struct validated by ValidateStruct or empty map if there are no errors.
Filter iterates over the slice and apply ConditionIterator to every item.
Find iterates over the slice and apply ConditionIterator to every item.
GetLine return specified line of multiline string.
GetLines split string by "\n" and return array of lines.
HasLowerCase check if the string contains at least 1 lowercase.
HasUpperCase check if the string contians as least 1 uppercase.
InRange returns true if value lies between left and right border, generic type to handle int, float32 or float64, all types must the same type.
InRange returns true if value lies between left and right border.
InRange returns true if value lies between left and right border.
InRange returns true if value lies between left and right border.
IsAlpha check if the string contains only letters (a-zA-Z).
IsAlphanumeric check if the string contains only letters and numbers.
IsASCII check if the string contains ASCII chars only.
IsBase64 check if a string is base64 encoded.
IsByteLength check if the string's length (in bytes) falls in a range.
IsCIDR check if the string is an valid CIDR notiation (IPV4 & IPV6).
IsCreditCard check if the string is a credit card.
IsDataURI checks if a string is base64 encoded data URI such as an image.
IsDialString validates the given string for usage with the various Dial() functions.
IsDivisibleBy check if the string is a number that's divisible by another.
IsDNSName will validate the given string as a DNS name.
IsEmail check if the string is an email.
IsFilePath check is a string is Win or Unix file path and returns it's type.
IsFloat check if the string is a float.
IsFullWidth check if the string contains any full-width chars.
IsHalfWidth check if the string contains any half-width chars.
IsHash checks if a string is a hash of type algorithm.
IsHexadecimal check if the string is a hexadecimal number.
IsHexcolor check if the string is a hexadecimal color.
IsHost checks if the string is a valid IP (both v4 and v6) or a valid DNS name.
IsIn check if string str is a member of the set of strings params.
IsInt check if the string is an integer.
IsIP checks if a string is either IP version 4 or 6.
IsIPv4 check if the string is an IP version 4.
IsIPv6 check if the string is an IP version 6.
IsISBN check if the string is an ISBN (version 10 or 13).
IsISBN10 check if the string is an ISBN version 10.
IsISBN13 check if the string is an ISBN version 13.
IsISO3166Alpha2 checks if a string is valid two-letter country code.
IsISO3166Alpha3 checks if a string is valid three-letter country code.
IsISO4217 check if string is valid ISO currency code.
IsISO693Alpha2 checks if a string is valid two-letter language code.
IsISO693Alpha3b checks if a string is valid three-letter language code.
IsJSON check if the string is valid JSON (note: uses json.Unmarshal).
IsLatitude check if a string is valid latitude.
IsLongitude check if a string is valid longitude.
IsLowerCase check if the string is lowercase.
IsMAC check if a string is valid MAC address.
IsMongoID check if the string is a valid hex-encoded representation of a MongoDB ObjectId.
IsMultibyte check if the string contains one or more multibyte chars.
IsNatural returns true if value is natural number (positive and whole).
IsNegative returns true if value < 0.
IsNonNegative returns true if value >= 0.
IsNonPositive returns true if value <= 0.
IsNull check if the string is null.
IsNumeric check if the string contains only numbers.
IsPort checks if a string represents a valid port.
IsPositive returns true if value > 0.
IsPrintableASCII check if the string contains printable ASCII chars only.
IsRequestURI check if the string rawurl, assuming it was received in an HTTP request, is an absolute URI or an absolute path.
IsRequestURL check if the string rawurl, assuming it was received in an HTTP request, is a valid URL confirm to RFC 3986.
IsRFC3339 check if string is valid timestamp value according to RFC3339.
IsRFC3339WithoutZone check if string is valid timestamp value according to RFC3339 which excludes the timezone.
IsRGBcolor check if the string is a valid RGB color in form rgb(RRR, GGG, BBB).
IsRsaPub check whether string is valid RSA key Alias for IsRsaPublicKey.
IsRsaPublicKey check if a string is valid public key with provided length.
IsSemver check if string is valid semantic version.
IsSSN will validate the given string as a U.S.
IsTime check if string is valid according to given format.
IsUpperCase check if the string is uppercase.
IsURL check if the string is an URL.
IsUTFDigit check if the string contains only unicode radix-10 decimal digits.
IsUTFLetter check if the string contains only unicode letter characters.Similar to IsAlpha but for all languages.
IsUTFLetterNumeric check if the string contains only unicode letters and numbers.
IsUTFNumeric check if the string contains only unicode numbers of any kind.
IsUUID check if the string is a UUID (version 3, 4 or 5).
IsUUIDv3 check if the string is a UUID version 3.
IsUUIDv4 check if the string is a UUID version 4.
IsUUIDv5 check if the string is a UUID version 5.
IsVariableWidth check if the string contains a mixture of full and half-width chars.
IsWhole returns true if value is whole number.
LeftTrim trim characters from the left-side of the input.
Map iterates over the slice and apply ResultIterator to every item.
Matches check if string matches the pattern (pattern is regular expression) In case of error return false.
NormalizeEmail canonicalize an email address.
PadBoth pad sides of string if size of string is less then indicated pad length.
PadLeft pad left side of string if size of string is less then indicated pad length.
PadRight pad right side of string if size of string is less then indicated pad length.
Range check string's length.
RemoveTags remove all tags from HTML string.
ReplacePattern replace regular expression pattern in string.
Reverse return reversed string.
RightTrim trim characters from the right-side of the input.
RuneLength check string's length Alias for StringLength.
SafeFileName return safe string that can be used in file names.
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"`).
Sign returns signum of number: 1 in case of value > 0, -1 in case of value < 0, 0 otherwise.
StringLength check string's length (including multi byte strings).
StringMatches checks if a string matches a given pattern.
StripLow remove characters with a numerical value < 32 and 127, mostly control characters.
ToBoolean convert the input string to a boolean.
ToFloat convert the input string to a float, or 0.0 if the input is not a float.
ToInt convert the input string to an integer, or 0 if the input is not an integer.
ToJSON convert the input to a valid JSON string.
ToString convert the input to a string.
Trim trim characters from both sides of the input.
Truncate a string to the closest length without breaking words.
UnderscoreToCamelCase converts from underscore separated form to camel case form.
ValidateStruct use tags for fields.
WhiteList remove characters that do not appear in the whitelist.
WrapOldParamValidatorSignature takes an old param validator signature and wraps it so it can be used with the new signature.
WrapOldValidatorSignature takes an old validator signature and wraps it so it can be used with the new signature.

# Constants

Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
No description provided by the author
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Unix is *nix OS types.
Basic regular expressions for validating strings.
Unknown is unresolved OS type.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Basic regular expressions for validating strings.
Win is Windows type.
Basic regular expressions for validating strings.

# Variables

CustomTypeTagMap is a map of functions that can be used as tags for ValidateStruct function.
Escape replace <, >, & and " with HTML entities.
ISO3166List based on https://www.iso.org/obp/ui/#search/code/ Code Type "Officially Assigned Codes".
ISO4217List is the list of ISO currency codes.
ISO693List based on http://data.okfn.org/data/core/language-codes/r/language-codes-3b2.json.
ParamTagMap is a map of functions accept variants parameters.
ParamTagRegexMap maps param tags to their respective regexes.
TagMap is a map of functions, that can be used as tags for ValidateStruct function.

# Structs

Error encapsulates a name, an error and whether there's a custom error message or not.
ISO3166Entry stores country codes.
ISO693Entry stores ISO language codes.
UnsupportedTypeError is a wrapper for reflect.Type.

# Type aliases

ConditionIterator is the function that accepts element of slice/array and its index and returns boolean.
CustomTypeValidator is a wrapper for validator functions that returns bool and accepts any type.
Errors is an array of multiple errors and conforms to the error interface.
Iterator is the function that accepts element of slice/array and its index.
ParamValidator is a wrapper for validator functions that accepts additional parameters.
ResultIterator is the function that accepts element of slice/array and its index and returns any result.
Validator is a wrapper for a validator function that returns bool and accepts string.