Releases: go-playground/validator
Release 7
v7 Released!
What about v6 being stable?
I know I said v6 was intended to be long term stable, and it was, the breaking change is so small, but a breaking change non the less so v7 is born.
What do I have to do to update/upgrade to v7?
Maybe nothing! read on...
The validation function has changed from
type Func func(topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldtype reflect.Type, fieldKind reflect.Kind, param string) boolto
type Func func(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldtype reflect.Type, fieldKind reflect.Kind, param string) boolSo if you have no custom functions v7 is a drop in replacement for v6!
If you do have custom functions all you have to do is add "v *Validate" as the first param; so pretty painless if you ask me.
What's New?
-
StructPartial and StructExcept, which was recently backported to v6
-
Cross Struct Cross field validation using tags via the following tags:
- eqcsfield
- necsfield
- gtcsfield
- gtecsfield
- ltcsfield
- ltecsfield
Example
type Inner struct { CreatedAt time.Time } type Outer struct { Inner *Inner CreatedAt time.Time `validate:"gtecsfield=Inner.CreatedAt"` } now := time.Now() Inner := &Inner{ CreatedAt: now, } outer := &Outer{ Inner: inner, CreatedAt: now, } errs := validate.Struct(outer) fmt.Println(errs)
Why have multiple cross field tag?
As an example why have eqfield and eqcsfield?
- because eqfield will validate against a field within the currentStruct i.e. same level but eqcsfield will get the field relative to the top struct or field, which may be multiple levels down; so in summary efficiency.
Benchmarks
Run on MacBook Pro (Retina, 15-inch, Late 2013) 2.6 GHz Intel Core i7 16 GB 1600 MHz DDR3 using Go 1.5
$ go test -cpu=4 -bench=. -benchmem=true
PASS
BenchmarkFieldSuccess-4 5000000 285 ns/op 16 B/op 1 allocs/op
BenchmarkFieldFailure-4 5000000 284 ns/op 16 B/op 1 allocs/op
BenchmarkFieldDiveSuccess-4 500000 2501 ns/op 384 B/op 19 allocs/op
BenchmarkFieldDiveFailure-4 500000 3022 ns/op 752 B/op 23 allocs/op
BenchmarkFieldCustomTypeSuccess-4 3000000 445 ns/op 32 B/op 2 allocs/op
BenchmarkFieldCustomTypeFailure-4 2000000 788 ns/op 416 B/op 6 allocs/op
BenchmarkFieldOrTagSuccess-4 1000000 1377 ns/op 32 B/op 2 allocs/op
BenchmarkFieldOrTagFailure-4 1000000 1201 ns/op 400 B/op 6 allocs/op
BenchmarkStructSimpleCustomTypeSuccess-4 1000000 1257 ns/op 80 B/op 5 allocs/op
BenchmarkStructSimpleCustomTypeFailure-4 1000000 1776 ns/op 608 B/op 13 allocs/op
BenchmarkStructPartialSuccess-4 1000000 1354 ns/op 400 B/op 11 allocs/op
BenchmarkStructPartialFailure-4 1000000 1813 ns/op 784 B/op 16 allocs/op
BenchmarkStructExceptSuccess-4 2000000 916 ns/op 368 B/op 9 allocs/op
BenchmarkStructExceptFailure-4 1000000 1369 ns/op 400 B/op 11 allocs/op
BenchmarkStructSimpleCrossFieldSuccess-4 1000000 1033 ns/op 128 B/op 6 allocs/op
BenchmarkStructSimpleCrossFieldFailure-4 1000000 1569 ns/op 528 B/op 11 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldSuccess-4 1000000 1371 ns/op 160 B/op 8 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldFailure-4 1000000 1935 ns/op 560 B/op 13 allocs/op
BenchmarkStructSimpleSuccess-4 1000000 1161 ns/op 48 B/op 3 allocs/op
BenchmarkStructSimpleFailure-4 1000000 1720 ns/op 560 B/op 11 allocs/op
BenchmarkStructSimpleSuccessParallel-4 5000000 329 ns/op 48 B/op 3 allocs/op
BenchmarkStructSimpleFailureParallel-4 2000000 625 ns/op 560 B/op 11 allocs/op
BenchmarkStructComplexSuccess-4 200000 6636 ns/op 432 B/op 27 allocs/op
BenchmarkStructComplexFailure-4 200000 11327 ns/op 2919 B/op 69 allocs/op
BenchmarkStructComplexSuccessParallel-4 1000000 1991 ns/op 432 B/op 27 allocs/op
BenchmarkStructComplexFailureParallel-4 500000 3854 ns/op 2920 B/op 69 allocs/opRelease 6.7
Summary
Backported v7 updates + additions from the near released v7.
Changes
- updated code to determine field type into a reusable function, making the code a little more DRY and allowing for future use in v7.
Additions
- Added StructPartial and StructExcept functions + tests + benchmarks
both StructPartial and StructExcept allow for conditional validation of a struct in order to ignore or explicitly define which fields that are to be validated for a given situation.
Although using separate structs or more than one validator with different TagName can solve this problem, and is usually the recommended approach, there are times where this would be necessary. An example would be that you are upgrading your current language to Go, but cannot redesign some of the data structure, essentially being stuck with some legacy structure.
Thanks @jtriber for the idea and help! fo request #149
Benchmarks
Splitting the type determination into a function did affect the ns/op ever so slightly.
go test -cpu=4 -bench=. -benchmem=true
PASS
BenchmarkFieldSuccess-4 5000000 337 ns/op 16 B/op 1 allocs/op
BenchmarkFieldFailure-4 5000000 331 ns/op 16 B/op 1 allocs/op
BenchmarkFieldCustomTypeSuccess-4 3000000 497 ns/op 32 B/op 2 allocs/op
BenchmarkFieldCustomTypeFailure-4 2000000 842 ns/op 416 B/op 6 allocs/op
BenchmarkFieldOrTagSuccess-4 500000 2432 ns/op 20 B/op 2 allocs/op
BenchmarkFieldOrTagFailure-4 1000000 1323 ns/op 384 B/op 6 allocs/op
BenchmarkStructSimpleCustomTypeSuccess-4 1000000 1409 ns/op 56 B/op 5 allocs/op
BenchmarkStructSimpleCustomTypeFailure-4 1000000 1876 ns/op 577 B/op 13 allocs/op
BenchmarkStructPartialSuccess-4 1000000 1438 ns/op 384 B/op 13 allocs/op
BenchmarkStructPartialFailure-4 1000000 2040 ns/op 785 B/op 18 allocs/op
BenchmarkStructExceptSuccess-4 1000000 1000 ns/op 368 B/op 11 allocs/op
BenchmarkStructExceptFailure-4 1000000 1431 ns/op 384 B/op 13 allocs/op
BenchmarkStructSimpleSuccess-4 1000000 1375 ns/op 24 B/op 3 allocs/op
BenchmarkStructSimpleFailure-4 1000000 1893 ns/op 529 B/op 11 allocs/op
BenchmarkStructSimpleSuccessParallel-4 5000000 362 ns/op 24 B/op 3 allocs/op
BenchmarkStructSimpleFailureParallel-4 2000000 883 ns/op 529 B/op 11 allocs/op
BenchmarkStructComplexSuccess-4 200000 8237 ns/op 368 B/op 30 allocs/op
BenchmarkStructComplexFailure-4 100000 12617 ns/op 2861 B/op 72 allocs/op
BenchmarkStructComplexSuccessParallel-4 1000000 2398 ns/op 368 B/op 30 allocs/op
BenchmarkStructComplexFailureParallel-4 300000 5733 ns/op 2862 B/op 72 allocs/opRelease 6.6
Updated relative import path accidentally left in when updating to v6, no functional changes.
thanks @ardan-bkennedy for the pull request: #155
Release 6.5.1
Updated Panic Tests after updates to assertion library
Release 6.5
Minor code cleanup, no functional changes
code cleanup, ran gofmt -s -w . on code, only a few changes.
Release 6.4
Add "exists" tag
exists
Is a special tag without a validation function attached. It is used when a field
is a Pointer, Interface or Invalid and you wish to validate that it exists.
Example: want to ensure a bool exists if you define the bool as a pointer and
use exists it will ensure there is a value; couldn't use required as it would
fail when the bool was false. exists will fail is the value is a Pointer, Interface
or Invalid and is nil. (Usage: exists)
see example in issue #142 thanks @davisford
Release 5.11
Add "exists" tag
exists
Is a special tag without a validation function attached. It is used when a field
is a Pointer, Interface or Invalid and you wish to validate that it exists.
Example: want to ensure a bool exists if you define the bool as a pointer and
use exists it will ensure there is a value; couldn't use required as it would
fail when the bool was false. exists will fail is the value is a Pointer, Interface
or Invalid and is nil. (Usage: exists)
see example in issue #142 thanks @davisford
Release 6.3
Add RegisterCustomTypeFunc for easier adding of CustomTypeFunc
see example in README or here: https://github.com/bluesuncorp/validator/blob/v6/examples/custom/custom.go
thanks @johnniedoe for the pull request
Release 6.2
Add Custom Field Type validation
Now if you have a type like say one that implements go's sql driver Valuer see here: https://golang.org/src/database/sql/driver/types.go?s=1210:1293#L29
You can add a custom validator for any type as long as it implements the new validator.CustomTypeFunc
see the README, I added an example usage.
This was all started with a request from @johnniedoe here #133 thanks again!
Added CustomType Benchmarks
as you can see this new functionality does not slow down the pre-existing benchmarks
$ go test -cpu=4 -bench=. -benchmem=true
PASS
BenchmarkFieldSuccess-4 5000000 318 ns/op 16 B/op 1 allocs/op
BenchmarkFieldFailure-4 5000000 316 ns/op 16 B/op 1 allocs/op
BenchmarkFieldCustomTypeSuccess-4 3000000 492 ns/op 32 B/op 2 allocs/op
BenchmarkFieldCustomTypeFailure-4 2000000 843 ns/op 416 B/op 6 allocs/op
BenchmarkFieldOrTagSuccess-4 500000 2384 ns/op 20 B/op 2 allocs/op
BenchmarkFieldOrTagFailure-4 1000000 1295 ns/op 384 B/op 6 allocs/op
BenchmarkStructSimpleSuccess-4 1000000 1175 ns/op 24 B/op 3 allocs/op
BenchmarkStructSimpleFailure-4 1000000 1822 ns/op 529 B/op 11 allocs/op
BenchmarkStructSimpleCustomTypeSuccess-4 1000000 1302 ns/op 56 B/op 5 allocs/op
BenchmarkStructSimpleCustomTypeFailure-4 1000000 1847 ns/op 577 B/op 13 allocs/op
BenchmarkStructSimpleSuccessParallel-4 5000000 339 ns/op 24 B/op 3 allocs/op
BenchmarkStructSimpleFailureParallel-4 2000000 733 ns/op 529 B/op 11 allocs/op
BenchmarkStructComplexSuccess-4 200000 7104 ns/op 368 B/op 30 allocs/op
BenchmarkStructComplexFailure-4 100000 11996 ns/op 2861 B/op 72 allocs/op
BenchmarkStructComplexSuccessParallel-4 1000000 2252 ns/op 368 B/op 30 allocs/op
BenchmarkStructComplexFailureParallel-4 300000 4691 ns/op 2862 B/op 72 allocs/opRelease 6.1.1
Added new validators:
- ip
- ipv4
- ipv6
- mac
see documentation for details https://godoc.org/gopkg.in/bluesuncorp/validator.v6