Skip to content

Releases: go-playground/validator

Release 7

20 Aug 01:08

Choose a tag to compare

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) bool

to

type Func func(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldtype reflect.Type, fieldKind reflect.Kind, param string) bool

So 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/op

Release 6.7

19 Aug 17:21

Choose a tag to compare

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

Release 6.6

19 Aug 12:42

Choose a tag to compare

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

17 Aug 12:30

Choose a tag to compare

Updated Panic Tests after updates to assertion library

Release 6.5

04 Aug 03:05

Choose a tag to compare

Minor code cleanup, no functional changes

code cleanup, ran gofmt -s -w . on code, only a few changes.

Release 6.4

04 Aug 01:38

Choose a tag to compare

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

04 Aug 01:37

Choose a tag to compare

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

02 Aug 01:02

Choose a tag to compare

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

31 Jul 02:32

Choose a tag to compare

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

Release 6.1.1

28 Jul 02:49

Choose a tag to compare

Added new validators:

  • ip
  • ipv4
  • ipv6
  • mac

see documentation for details https://godoc.org/gopkg.in/bluesuncorp/validator.v6