💯Go Struct and Field validation, including Cross Field, Cross Struct, Map, Slice and Array diving
Find a file
Dean Karn 9ba3297c49 Update benchmarks run against Go 1.7
Go 1.7 some nice boosts, for nothing!

```

benchmark                                                       old ns/op     new ns/op     delta
BenchmarkFieldSuccess-8                                         147           108           -26.53%
BenchmarkFieldSuccessParallel-8                                 42.5          35.7          -16.00%
BenchmarkFieldFailure-8                                         417           320           -23.26%
BenchmarkFieldFailureParallel-8                                 140           113           -19.29%
BenchmarkFieldDiveSuccess-8                                     876           726           -17.12%
BenchmarkFieldDiveSuccessParallel-8                             277           263           -5.05%
BenchmarkFieldDiveFailure-8                                     1185          939           -20.76%
BenchmarkFieldDiveFailureParallel-8                             402           382           -4.98%
BenchmarkFieldCustomTypeSuccess-8                               321           268           -16.51%
BenchmarkFieldCustomTypeSuccessParallel-8                       104           87.8          -15.58%
BenchmarkFieldCustomTypeFailure-8                               416           310           -25.48%
BenchmarkFieldCustomTypeFailureParallel-8                       150           131           -12.67%
BenchmarkFieldOrTagSuccess-8                                    1119          889           -20.55%
BenchmarkFieldOrTagSuccessParallel-8                            462           418           -9.52%
BenchmarkFieldOrTagFailure-8                                    715           546           -23.64%
BenchmarkFieldOrTagFailureParallel-8                            436           450           +3.21%
BenchmarkStructLevelValidationSuccess-8                         399           336           -15.79%
BenchmarkStructLevelValidationSuccessParallel-8                 140           123           -12.14%
BenchmarkStructLevelValidationFailure-8                         749           611           -18.42%
BenchmarkStructLevelValidationFailureParallel-8                 296           298           +0.68%
BenchmarkStructSimpleCustomTypeSuccess-8                        673           555           -17.53%
BenchmarkStructSimpleCustomTypeSuccessParallel-8                213           197           -7.51%
BenchmarkStructSimpleCustomTypeFailure-8                        1056          811           -23.20%
BenchmarkStructSimpleCustomTypeFailureParallel-8                450           370           -17.78%
BenchmarkStructPartialSuccess-8                                 789           676           -14.32%
BenchmarkStructPartialSuccessParallel-8                         307           301           -1.95%
BenchmarkStructPartialFailure-8                                 1105          1001          -9.41%
BenchmarkStructPartialFailureParallel-8                         493           436           -11.56%
BenchmarkStructExceptSuccess-8                                  1212          1038          -14.36%
BenchmarkStructExceptSuccessParallel-8                          282           281           -0.35%
BenchmarkStructExceptFailure-8                                  1004          863           -14.04%
BenchmarkStructExceptFailureParallel-8                          452           379           -16.15%
BenchmarkStructSimpleCrossFieldSuccess-8                        656           549           -16.31%
BenchmarkStructSimpleCrossFieldSuccessParallel-8                211           192           -9.00%
BenchmarkStructSimpleCrossFieldFailure-8                        968           783           -19.11%
BenchmarkStructSimpleCrossFieldFailureParallel-8                406           296           -27.09%
BenchmarkStructSimpleCrossStructCrossFieldSuccess-8             1000          837           -16.30%
BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8     334           284           -14.97%
BenchmarkStructSimpleCrossStructCrossFieldFailure-8             1324          1110          -16.16%
BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8     520           416           -20.00%
BenchmarkStructSimpleSuccess-8                                  534           380           -28.84%
BenchmarkStructSimpleSuccessParallel-8                          144           114           -20.83%
BenchmarkStructSimpleFailure-8                                  1039          760           -26.85%
BenchmarkStructSimpleFailureParallel-8                          419           353           -15.75%
BenchmarkStructComplexSuccess-8                                 2678          2100          -21.58%
BenchmarkStructComplexSuccessParallel-8                         874           662           -24.26%
BenchmarkStructComplexFailure-8                                 6342          5080          -19.90%
BenchmarkStructComplexFailureParallel-8                         2875          2159          -24.90%

benchmark                                                       old allocs     new allocs     delta
BenchmarkFieldSuccess-8                                         0              0              +0.00%
BenchmarkFieldSuccessParallel-8                                 0              0              +0.00%
BenchmarkFieldFailure-8                                         4              4              +0.00%
BenchmarkFieldFailureParallel-8                                 4              4              +0.00%
BenchmarkFieldDiveSuccess-8                                     11             11             +0.00%
BenchmarkFieldDiveSuccessParallel-8                             11             11             +0.00%
BenchmarkFieldDiveFailure-8                                     16             16             +0.00%
BenchmarkFieldDiveFailureParallel-8                             16             16             +0.00%
BenchmarkFieldCustomTypeSuccess-8                               2              2              +0.00%
BenchmarkFieldCustomTypeSuccessParallel-8                       2              2              +0.00%
BenchmarkFieldCustomTypeFailure-8                               4              4              +0.00%
BenchmarkFieldCustomTypeFailureParallel-8                       4              4              +0.00%
BenchmarkFieldOrTagSuccess-8                                    1              1              +0.00%
BenchmarkFieldOrTagSuccessParallel-8                            1              1              +0.00%
BenchmarkFieldOrTagFailure-8                                    5              5              +0.00%
BenchmarkFieldOrTagFailureParallel-8                            5              5              +0.00%
BenchmarkStructLevelValidationSuccess-8                         2              2              +0.00%
BenchmarkStructLevelValidationSuccessParallel-8                 2              2              +0.00%
BenchmarkStructLevelValidationFailure-8                         8              8              +0.00%
BenchmarkStructLevelValidationFailureParallel-8                 8              8              +0.00%
BenchmarkStructSimpleCustomTypeSuccess-8                        2              2              +0.00%
BenchmarkStructSimpleCustomTypeSuccessParallel-8                2              2              +0.00%
BenchmarkStructSimpleCustomTypeFailure-8                        9              9              +0.00%
BenchmarkStructSimpleCustomTypeFailureParallel-8                10             10             +0.00%
BenchmarkStructPartialSuccess-8                                 6              6              +0.00%
BenchmarkStructPartialSuccessParallel-8                         6              6              +0.00%
BenchmarkStructPartialFailure-8                                 11             11             +0.00%
BenchmarkStructPartialFailureParallel-8                         11             11             +0.00%
BenchmarkStructExceptSuccess-8                                  12             12             +0.00%
BenchmarkStructExceptSuccessParallel-8                          5              5              +0.00%
BenchmarkStructExceptFailure-8                                  10             10             +0.00%
BenchmarkStructExceptFailureParallel-8                          10             10             +0.00%
BenchmarkStructSimpleCrossFieldSuccess-8                        3              3              +0.00%
BenchmarkStructSimpleCrossFieldSuccessParallel-8                3              3              +0.00%
BenchmarkStructSimpleCrossFieldFailure-8                        8              8              +0.00%
BenchmarkStructSimpleCrossFieldFailureParallel-8                8              8              +0.00%
BenchmarkStructSimpleCrossStructCrossFieldSuccess-8             4              4              +0.00%
BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8     4              4              +0.00%
BenchmarkStructSimpleCrossStructCrossFieldFailure-8             9              9              +0.00%
BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8     9              9              +0.00%
BenchmarkStructSimpleSuccess-8                                  0              0              +0.00%
BenchmarkStructSimpleSuccessParallel-8                          0              0              +0.00%
BenchmarkStructSimpleFailure-8                                  9              9              +0.00%
BenchmarkStructSimpleFailureParallel-8                          9              9              +0.00%
BenchmarkStructComplexSuccess-8                                 8              8              +0.00%
BenchmarkStructComplexSuccessParallel-8                         8              8              +0.00%
BenchmarkStructComplexFailure-8                                 53             53             +0.00%
BenchmarkStructComplexFailureParallel-8                         53             53             +0.00%

benchmark                                                       old bytes     new bytes     delta
BenchmarkFieldSuccess-8                                         0             0             +0.00%
BenchmarkFieldSuccessParallel-8                                 0             0             +0.00%
BenchmarkFieldFailure-8                                         192           192           +0.00%
BenchmarkFieldFailureParallel-8                                 192           192           +0.00%
BenchmarkFieldDiveSuccess-8                                     201           201           +0.00%
BenchmarkFieldDiveSuccessParallel-8                             201           201           +0.00%
BenchmarkFieldDiveFailure-8                                     396           396           +0.00%
BenchmarkFieldDiveFailureParallel-8                             397           397           +0.00%
BenchmarkFieldCustomTypeSuccess-8                               32            32            +0.00%
BenchmarkFieldCustomTypeSuccessParallel-8                       32            32            +0.00%
BenchmarkFieldCustomTypeFailure-8                               192           192           +0.00%
BenchmarkFieldCustomTypeFailureParallel-8                       192           192           +0.00%
BenchmarkFieldOrTagSuccess-8                                    16            16            +0.00%
BenchmarkFieldOrTagSuccessParallel-8                            16            16            +0.00%
BenchmarkFieldOrTagFailure-8                                    208           208           +0.00%
BenchmarkFieldOrTagFailureParallel-8                            208           208           +0.00%
BenchmarkStructLevelValidationSuccess-8                         32            32            +0.00%
BenchmarkStructLevelValidationSuccessParallel-8                 32            32            +0.00%
BenchmarkStructLevelValidationFailure-8                         288           288           +0.00%
BenchmarkStructLevelValidationFailureParallel-8                 288           288           +0.00%
BenchmarkStructSimpleCustomTypeSuccess-8                        32            32            +0.00%
BenchmarkStructSimpleCustomTypeSuccessParallel-8                32            32            +0.00%
BenchmarkStructSimpleCustomTypeFailure-8                        392           392           +0.00%
BenchmarkStructSimpleCustomTypeFailureParallel-8                408           408           +0.00%
BenchmarkStructPartialSuccess-8                                 256           256           +0.00%
BenchmarkStructPartialSuccessParallel-8                         256           256           +0.00%
BenchmarkStructPartialFailure-8                                 464           464           +0.00%
BenchmarkStructPartialFailureParallel-8                         464           464           +0.00%
BenchmarkStructExceptSuccess-8                                  480           480           +0.00%
BenchmarkStructExceptSuccessParallel-8                          240           240           +0.00%
BenchmarkStructExceptFailure-8                                  448           448           +0.00%
BenchmarkStructExceptFailureParallel-8                          448           448           +0.00%
BenchmarkStructSimpleCrossFieldSuccess-8                        72            72            +0.00%
BenchmarkStructSimpleCrossFieldSuccessParallel-8                72            72            +0.00%
BenchmarkStructSimpleCrossFieldFailure-8                        288           288           +0.00%
BenchmarkStructSimpleCrossFieldFailureParallel-8                288           288           +0.00%
BenchmarkStructSimpleCrossStructCrossFieldSuccess-8             80            80            +0.00%
BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8     80            80            +0.00%
BenchmarkStructSimpleCrossStructCrossFieldFailure-8             304           304           +0.00%
BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8     304           304           +0.00%
BenchmarkStructSimpleSuccess-8                                  0             0             +0.00%
BenchmarkStructSimpleSuccessParallel-8                          0             0             +0.00%
BenchmarkStructSimpleFailure-8                                  392           392           +0.00%
BenchmarkStructSimpleFailureParallel-8                          392           392           +0.00%
BenchmarkStructComplexSuccess-8                                 128           128           +0.00%
BenchmarkStructComplexSuccessParallel-8                         128           128           +0.00%
BenchmarkStructComplexFailure-8                                 2833          2833          +0.00%
BenchmarkStructComplexFailureParallel-8                         2833          2833          +0.00%

```
2016-08-23 16:10:39 -04:00
examples RC1 Release 2016-08-08 09:54:52 -04:00
.gitignore update nefield and necsfield to hav own logic instead of calling !eqfield... 2015-08-19 20:17:28 -04:00
baked_in.go working instance 2016-08-03 14:46:35 -04:00
benchmarks_test.go add parallel versions of all benchmarks 2016-08-06 21:47:16 -04:00
cache.go saving some bytes uint8 vs int 2016-08-06 20:41:38 -04:00
doc.go RC1 Release 2016-08-08 09:54:52 -04:00
errors.go saving some bytes uint8 vs int 2016-08-06 20:41:38 -04:00
examples_test.go working instance 2016-08-03 14:46:35 -04:00
field_level.go finish conversion of test + some fixes. 2016-08-04 11:00:01 -04:00
LICENSE Initial commit 2015-02-12 11:32:22 -05:00
logo.png Added logo to ReadMe 2015-11-30 23:37:32 -05:00
README.md Update benchmarks run against Go 1.7 2016-08-23 16:10:39 -04:00
regexes.go inline Regex calls 2015-09-02 20:57:31 -04:00
struct_level.go saving some bytes uint8 vs int 2016-08-06 20:41:38 -04:00
util.go working instance 2016-08-03 14:46:35 -04:00
validator.go saving some bytes uint8 vs int 2016-08-06 20:41:38 -04:00
validator_instance.go increase dive tag performance. 2016-08-06 13:55:36 -04:00
validator_test.go continuing perf optimizations 2016-08-06 15:23:45 -04:00

Package validator

[![Join the chat at https://gitter.im/bluesuncorp/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ![Project status](https://img.shields.io/badge/RC1-9.0.0-yellow.svg) [![Build Status](https://semaphoreci.com/api/v1/projects/ec20115f-ef1b-4c7d-9393-cc76aba74eb4/530054/badge.svg)](https://semaphoreci.com/joeybloggs/validator) [![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=v9&service=github)](https://coveralls.io/github/go-playground/validator?branch=v9) [![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator) [![GoDoc](https://godoc.org/gopkg.in/go-playground/validator.v9?status.svg)](https://godoc.org/gopkg.in/go-playground/validator.v9) ![License](https://img.shields.io/dub/l/vibe-d.svg)

Package validator implements value validations for structs and individual fields based on tags.

It has the following unique features:

  • Cross Field and Cross Struct validations by using validation tags or custom validators.
  • Slice, Array and Map diving, which allows any or all levels of a multidimensional field to be validated.
  • Handles type interface by determining it's underlying type prior to validation.
  • Handles custom field types such as sql driver Valuer see Valuer
  • Alias validation tags, which allows for mapping of several validations to a single tag for easier defining of validations on structs
  • Extraction of custom defined Field Name e.g. can specify to extract the JSON name while validating and have it available in the resulting FieldError

Installation

Use go get.

go get gopkg.in/go-playground/validator.v9

or to update

go get -u gopkg.in/go-playground/validator.v9

Then import the validator package into your own code.

import "gopkg.in/go-playground/validator.v9"

Error Return Value

Validation functions return type error

They return type error to avoid the issue discussed in the following, where err is always != nil:

Validator only InvalidValidationError for bad validation input, nil or ValidationErrors as type error; so, in your code all you need to do is check if the error returned is not nil, and if it's not check if error is InvalidValidationError ( if necessary, most of the time it isn't ) type cast it to type ValidationErrors like so:

err := validate.Struct(mystruct)
validationErrors := err.(validator.ValidationErrors)

Usage and documentation

Please see http://godoc.org/gopkg.in/go-playground/validator.v9 for detailed usage docs.

Examples:

Struct & Field validation

package main

import (
	"fmt"

	"gopkg.in/go-playground/validator.v9"
)

// User contains user information
type User struct {
	FirstName      string     `validate:"required"`
	LastName       string     `validate:"required"`
	Age            uint8      `validate:"gte=0,lte=130"`
	Email          string     `validate:"required,email"`
	FavouriteColor string     `validate:"iscolor"`                // alias for 'hexcolor|rgb|rgba|hsl|hsla'
	Addresses      []*Address `validate:"required,dive,required"` // a person can have a home and cottage...
}

// Address houses a users address information
type Address struct {
	Street string `validate:"required"`
	City   string `validate:"required"`
	Planet string `validate:"required"`
	Phone  string `validate:"required"`
}

// use a single instance of Validate, it caches struct info
var validate *validator.Validate

func main() {

	validate = validator.New()

	validateStruct()
	validateVariable()
}

func validateStruct() {

	address := &Address{
		Street: "Eavesdown Docks",
		Planet: "Persphone",
		Phone:  "none",
	}

	user := &User{
		FirstName:      "Badger",
		LastName:       "Smith",
		Age:            135,
		Email:          "Badger.Smith@gmail.com",
		FavouriteColor: "#000-",
		Addresses:      []*Address{address},
	}

	// returns nil or ValidationErrors ( map[string]*FieldError )
	err := validate.Struct(user)
	if err != nil {

		// this check is only needed when your code could produce
		// an invalid value for validation such as interface with nil
		// value most including myself do not usually have code like this.
		if _, ok := err.(*validator.InvalidValidationError); ok {
			fmt.Println(err)
			return
		}

		for _, err := range err.(validator.ValidationErrors) {

			fmt.Println(err.Namespace())
			fmt.Println(err.Field())
			fmt.Println(err.StructNamespace()) // can differ when a custom TagNameFunc is registered or
			fmt.Println(err.StructField())     // by passing alt name to ReportError like below
			fmt.Println(err.Tag())
			fmt.Println(err.ActualTag())
			fmt.Println(err.Kind())
			fmt.Println(err.Type())
			fmt.Println(err.Value())
			fmt.Println(err.Param())
			fmt.Println()
		}

		// from here you can create your own error messages in whatever language you wish
		return
	}

	// save user to database
}

func validateVariable() {

	myEmail := "joeybloggs.gmail.com"

	errs := validate.Var(myEmail, "required,email")

	if errs != nil {
		fmt.Println(errs) // output: Key: "" Error:Field validation for "" failed on the "email" tag
		return
	}

	// email ok, move on
}

Custom Field Type

package main

import (
	"database/sql"
	"database/sql/driver"
	"fmt"
	"reflect"

	"gopkg.in/go-playground/validator.v9"
)

// DbBackedUser User struct
type DbBackedUser struct {
	Name sql.NullString `validate:"required"`
	Age  sql.NullInt64  `validate:"required"`
}

// use a single instance of Validate, it caches struct info
var validate *validator.Validate

func main() {

	validate = validator.New()

	// register all sql.Null* types to use the ValidateValuer CustomTypeFunc
	validate.RegisterCustomTypeFunc(ValidateValuer, sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{})

	// build object for validation
	x := DbBackedUser{Name: sql.NullString{String: "", Valid: true}, Age: sql.NullInt64{Int64: 0, Valid: false}}

	err := validate.Struct(x)

	if err != nil {
		fmt.Printf("Err(s):\n%+v\n", err)
	}
}

// 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
}

Struct Level Validation

package main

import (
	"fmt"

	"gopkg.in/go-playground/validator.v9"
)

// User contains user information
type User struct {
	FirstName      string     `json:"fname"`
	LastName       string     `json:"lname"`
	Age            uint8      `validate:"gte=0,lte=130"`
	Email          string     `validate:"required,email"`
	FavouriteColor string     `validate:"hexcolor|rgb|rgba"`
	Addresses      []*Address `validate:"required,dive,required"` // a person can have a home and cottage...
}

// Address houses a users address information
type Address struct {
	Street string `validate:"required"`
	City   string `validate:"required"`
	Planet string `validate:"required"`
	Phone  string `validate:"required"`
}

// use a single instance of Validate, it caches struct info
var validate *validator.Validate

func main() {

	validate = validator.New()

	// register validation for 'User'
	// NOTE: only have to register a non-pointer type for 'User', validator
	// interanlly dereferences during it's type checks.
	validate.RegisterStructValidation(UserStructLevelValidation, User{})

	// build 'User' info, normally posted data etc...
	address := &Address{
		Street: "Eavesdown Docks",
		Planet: "Persphone",
		Phone:  "none",
		City:   "Unknown",
	}

	user := &User{
		FirstName:      "",
		LastName:       "",
		Age:            45,
		Email:          "Badger.Smith@gmail.com",
		FavouriteColor: "#000",
		Addresses:      []*Address{address},
	}

	// returns InvalidValidationError for bad validation input, nil or ValidationErrors ( []FieldError )
	err := validate.Struct(user)
	if err != nil {

		// this check is only needed when your code could produce
		// an invalid value for validation such as interface with nil
		// value most including myself do not usually have code like this.
		if _, ok := err.(*validator.InvalidValidationError); ok {
			fmt.Println(err)
			return
		}

		for _, err := range err.(validator.ValidationErrors) {

			fmt.Println(err.Namespace())
			fmt.Println(err.Field())
			fmt.Println(err.StructNamespace()) // can differ when a custom TagNameFunc is registered or
			fmt.Println(err.StructField())     // by passing alt name to ReportError like below
			fmt.Println(err.Tag())
			fmt.Println(err.ActualTag())
			fmt.Println(err.Kind())
			fmt.Println(err.Type())
			fmt.Println(err.Value())
			fmt.Println(err.Param())
			fmt.Println()
		}

		// from here you can create your own error messages in whatever language you wish
		return
	}

	// save user to database
}

// UserStructLevelValidation contains custom struct level validations that don't always
// make sense at the field validation level. For Example this function validates that either
// FirstName or LastName exist; could have done that with a custom field validation but then
// would have had to add it to both fields duplicating the logic + overhead, this way it's
// only validated once.
//
// NOTE: you may ask why wouldn't I just do this outside of validator, because doing this way
// hooks right into validator and you can combine with validation tags and still have a
// common error output format.
func UserStructLevelValidation(sl validator.StructLevel) {

	user := sl.Current().Interface().(User)

	if len(user.FirstName) == 0 && len(user.LastName) == 0 {
		sl.ReportError(user.FirstName, "FirstName", "fname", "fnameorlname", "")
		sl.ReportError(user.LastName, "LastName", "lname", "fnameorlname", "")
	}

	// plus can to more, even with different tag than "fnameorlname"
}

Benchmarks

Run on MacBook Pro (Retina, 15-inch, Late 2013) 2.6 GHz Intel Core i7 16 GB 1600 MHz DDR3 using Go version go1.7 darwin/amd64
BenchmarkFieldSuccess-8                                        	20000000       	       108 ns/op       	       0 B/op  	       0 allocs/op
BenchmarkFieldSuccessParallel-8                                	50000000       	        35.7 ns/op     	       0 B/op  	       0 allocs/op
BenchmarkFieldFailure-8                                        	 5000000       	       320 ns/op       	     192 B/op  	       4 allocs/op
BenchmarkFieldFailureParallel-8                                	20000000       	       113 ns/op       	     192 B/op  	       4 allocs/op
BenchmarkFieldDiveSuccess-8                                    	 2000000       	       726 ns/op       	     201 B/op  	      11 allocs/op
BenchmarkFieldDiveSuccessParallel-8                            	10000000       	       263 ns/op       	     201 B/op  	      11 allocs/op
BenchmarkFieldDiveFailure-8                                    	 2000000       	       939 ns/op       	     396 B/op  	      16 allocs/op
BenchmarkFieldDiveFailureParallel-8                            	 5000000       	       382 ns/op       	     397 B/op  	      16 allocs/op
BenchmarkFieldCustomTypeSuccess-8                              	 5000000       	       268 ns/op       	      32 B/op  	       2 allocs/op
BenchmarkFieldCustomTypeSuccessParallel-8                      	20000000       	        87.8 ns/op     	      32 B/op  	       2 allocs/op
BenchmarkFieldCustomTypeFailure-8                              	 5000000       	       310 ns/op       	     192 B/op  	       4 allocs/op
BenchmarkFieldCustomTypeFailureParallel-8                      	20000000       	       131 ns/op       	     192 B/op  	       4 allocs/op
BenchmarkFieldOrTagSuccess-8                                   	 2000000       	       889 ns/op       	      16 B/op  	       1 allocs/op
BenchmarkFieldOrTagSuccessParallel-8                           	 5000000       	       418 ns/op       	      16 B/op  	       1 allocs/op
BenchmarkFieldOrTagFailure-8                                   	 3000000       	       546 ns/op       	     208 B/op  	       5 allocs/op
BenchmarkFieldOrTagFailureParallel-8                           	 3000000       	       450 ns/op       	     208 B/op  	       5 allocs/op
BenchmarkStructLevelValidationSuccess-8                        	 5000000       	       336 ns/op       	      32 B/op  	       2 allocs/op
BenchmarkStructLevelValidationSuccessParallel-8                	20000000       	       123 ns/op       	      32 B/op  	       2 allocs/op
BenchmarkStructLevelValidationFailure-8                        	 2000000       	       611 ns/op       	     288 B/op  	       8 allocs/op
BenchmarkStructLevelValidationFailureParallel-8                	 5000000       	       298 ns/op       	     288 B/op  	       8 allocs/op
BenchmarkStructSimpleCustomTypeSuccess-8                       	 2000000       	       555 ns/op       	      32 B/op  	       2 allocs/op
BenchmarkStructSimpleCustomTypeSuccessParallel-8               	10000000       	       197 ns/op       	      32 B/op  	       2 allocs/op
BenchmarkStructSimpleCustomTypeFailure-8                       	 2000000       	       811 ns/op       	     392 B/op  	       9 allocs/op
BenchmarkStructSimpleCustomTypeFailureParallel-8               	 5000000       	       370 ns/op       	     408 B/op  	      10 allocs/op
BenchmarkStructPartialSuccess-8                                	 2000000       	       676 ns/op       	     256 B/op  	       6 allocs/op
BenchmarkStructPartialSuccessParallel-8                        	 5000000       	       301 ns/op       	     256 B/op  	       6 allocs/op
BenchmarkStructPartialFailure-8                                	 1000000       	      1001 ns/op       	     464 B/op  	      11 allocs/op
BenchmarkStructPartialFailureParallel-8                        	 3000000       	       436 ns/op       	     464 B/op  	      11 allocs/op
BenchmarkStructExceptSuccess-8                                 	 1000000       	      1038 ns/op       	     480 B/op  	      12 allocs/op
BenchmarkStructExceptSuccessParallel-8                         	10000000       	       281 ns/op       	     240 B/op  	       5 allocs/op
BenchmarkStructExceptFailure-8                                 	 2000000       	       863 ns/op       	     448 B/op  	      10 allocs/op
BenchmarkStructExceptFailureParallel-8                         	 3000000       	       379 ns/op       	     448 B/op  	      10 allocs/op
BenchmarkStructSimpleCrossFieldSuccess-8                       	 3000000       	       549 ns/op       	      72 B/op  	       3 allocs/op
BenchmarkStructSimpleCrossFieldSuccessParallel-8               	10000000       	       192 ns/op       	      72 B/op  	       3 allocs/op
BenchmarkStructSimpleCrossFieldFailure-8                       	 2000000       	       783 ns/op       	     288 B/op  	       8 allocs/op
BenchmarkStructSimpleCrossFieldFailureParallel-8               	 5000000       	       296 ns/op       	     288 B/op  	       8 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldSuccess-8            	 2000000       	       837 ns/op       	      80 B/op  	       4 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8    	 5000000       	       284 ns/op       	      80 B/op  	       4 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldFailure-8            	 1000000       	      1110 ns/op       	     304 B/op  	       9 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8    	 3000000       	       416 ns/op       	     304 B/op  	       9 allocs/op
BenchmarkStructSimpleSuccess-8                                 	 5000000       	       380 ns/op       	       0 B/op  	       0 allocs/op
BenchmarkStructSimpleSuccessParallel-8                         	20000000       	       114 ns/op       	       0 B/op  	       0 allocs/op
BenchmarkStructSimpleFailure-8                                 	 2000000       	       760 ns/op       	     392 B/op  	       9 allocs/op
BenchmarkStructSimpleFailureParallel-8                         	 5000000       	       353 ns/op       	     392 B/op  	       9 allocs/op
BenchmarkStructComplexSuccess-8                                	 1000000       	      2100 ns/op       	     128 B/op  	       8 allocs/op
BenchmarkStructComplexSuccessParallel-8                        	 2000000       	       662 ns/op       	     128 B/op  	       8 allocs/op
BenchmarkStructComplexFailure-8                                	  200000       	      5080 ns/op       	    2833 B/op  	      53 allocs/op
BenchmarkStructComplexFailureParallel-8                        	 1000000       	      2159 ns/op       	    2833 B/op  	      53 allocs/op

Complimentary Software

Here is a list of software that compliments using this library either pre or post validation.

  • form - Decodes url.Values into Go value(s) and Encodes Go value(s) into url.Values. Dual Array and Full map support.
  • Conform - Trims, sanitizes & scrubs data based on struct tags.

How to Contribute

Make a pull request...

License

Distributed under MIT License, please see license file in code for more details.