genval
                                
                                 genval copied to clipboard
                                
                                    genval copied to clipboard
                            
                            
                            
                        Generates Validate() methods for structs by tags
genval  
 
Generates Validate() methods for all structs in package by tags
- no reflection in generated code - it means fast
- possibilities to override generated behavior
- can be used as //go:generate genval pkg
- Enum support
Installation
go get github.com/gojuno/genval
Usage
type User struct {
    Name    string  `validate:"max_len=64"`
    Age     uint    `validate:"min=18"`
    Emails []string `validate:"min_items=1,item=[min_len=5]"`
}
//generates:
func (r User) Validate() error {
    if utf8.RuneCountInString(r.Name) > 64 {
        return fmt.Errorf("field Name is longer than 64 chars")
    }
    if r.Age < 18 {
        return fmt.Errorf("field Age is shorter than 18 chars")
    }
    if len(r.Emails) < 1 {
        return fmt.Errorf("array Emails has less items than 1 ")
    }
    for _, x := range r.Emails {
        _ = x
        if utf8.RuneCountInString(x) < 5 {
            return fmt.Errorf("field x is shorter than 5 chars")
        }
    }
    return nil
}
Some other examples:
How to generate?
genval mypkg
or you can use it as go:generate directive
//go:generate genval mypkg
Supported tags
- String: min_len, max_len - min and max valid lenghth
- Number: min, max - min and max valid value (can be float)
- Array:  min_items, max_items - min and max count of items in array
 item - scope tag, contains validation tags for each item
- Pointer: nullable, not_null - it's clear
- Interface: func - the same as for struct (func NameOfTheFunc(i interface{})error{..})
- Struct: func - name of the method of this struct (func(s Struct) MethodName()error{..})
 or name of the func that will be used for validation (func nameOfTheFunc(s Struct)error{..})
 Methods should starts from '.'
 Can be used not once:func=.MethodName,func=nameOfTheFuncor evenfunc=.MethodName;nameOfTheFunc
- Map: min_items, max_items - min and max count of items in map
 key, value - scope tags, contains validation tags for key or value
Enum support
Go doesn`t support enums, but you can create some custom type and add few constants with required values.
type State int
const (
    StateOk    State = 200
    StateError State = 400
)
//generates:
func (r State) Validate() error {
    switch r {
    case StateOk:
    case StateError:
    default:
        return fmt.Errorf("invalid value for enum State: %v", r)
    }
    return nil
}
Some tips
- don`t use interface{} if you can
- commit generated code under source control
- read generated code if needed, do not afraid it
Custom validation
Additional validation
In some cases it`s required to add some custom validation. You can just add unexported validate method.
type User struct {
    Name  string `validate:"max_len=64"`
    Age   uint   `validate:"min=16"`
    Email string
}
func (u User) validate() error {
    if u.Age < 18 && u.Email == "" {
        return errors.New("email is required for people younger than 18")
    }
    return nil
}
// generates:
func (r User) Validate() error {
	if utf8.RuneCountInString(r.Name) > 64 {
		return fmt.Errorf("field Name is longer than 64 chars")
	}
	if r.Age < 16 {
		return fmt.Errorf("field Age is less than 16 ")
	}
	return r.validate() // custom validation call
}
Override validation
If you don`t want to use genval for some structs or use just custom validation then you can override exported Validate method. In this case genval will generate nothing for this struct.