Skip to content

tiendc/go-validator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

59 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go Version GoDoc Build Status Coverage Status GoReport

Fast and intuitive validation library for Go

This lib uses the Is... validation functions from the govalidator project.

Installation

go get github.com/tiendc/go-validator

Usage

General usage

 import ( vld "github.com/tiendc/go-validator" ) type Person struct { FirstName string LastName string Birthdate time.Time Unemployed bool Salary uint Rank string WorkEmail string Projects []string TaskMap map[string]Task } var p Person errs := vld.Validate( // Validate first and last names separately vld.StrLen(&p.FirstName, 3, 30).OnError( vld.SetField("first_name", nil), vld.SetCustomKey("ERR_VLD_PERSON_FIRST_NAME_INVALID"), ), vld.StrLen(&p.FirstName, 3, 30).OnError( vld.SetField("last_name", nil), vld.SetCustomKey("ERR_VLD_PERSON_LAST_NAME_INVALID"), ), // OR use this to produce only one error when one of them fails vld.Group( vld.StrLen(&p.FirstName, 3, 30), vld.StrLen(&p.LastName, 3, 30), ).OnError( vld.SetField("name", nil), vld.SetCustomKey("ERR_VLD_PERSON_NAME_INVALID"), ), // Birthdate is optional, but when it's present, it must be within 1950 and now vld.When(!p.Birthdate.IsZero()).Then( vld.TimeRange(p.Birthdate, <1950-01-01>, time.Now()).OnError(...), ) vld.When(!p.Unemployed).Then( vld.Required(&p.Salary), // Work email must be valid vld.StrIsEmail(&p.WorkEmail), // Rank must be one of the constants vld.StrIn(&p.Rank, "Employee", "Manager", "Director"), vld.Case( vld.When(p.Rank == "Manager").Then(vld.NumGT(&p.Salary, 10000)), vld.When(p.Rank == "Director").Then(vld.NumGT(&p.Salary, 30000)), ).Default( vld.NumLT(&p.Salary, 10000), ), // Projects are optional, but when they are present, they must be unique and sorted vld.When(len(p.Projects) > 0).Then( vld.SliceUnique(p.Projects).OnError(...), vld.SliceSorted(p.Projects).OnError(...), ) ).Else( // When person is unemployed vld.NumEQ(&p.Salary, 0), vld.StrEQ(&p.WorkEmail, ""), ), // Validate slice elements vld.Slice(p.Projects).ForEach(func(elem int, index int, validator ItemValidator) { validator.Validate( vld.StrLen(&elem, 10, 30).OnError( vld.SetField(fmt.Sprintf("projects[%d]", index), nil), vld.SetCustomKey("ERR_VLD_PROJECT_NAME_INVALID"), ), ) }), // Validate map entries vld.Map(p.TaskMap).ForEach(func(k string, v Task, validator ItemValidator) { validator.Validate( vld.StrLen(&v.Name, 10, 30).OnError( vld.SetField(fmt.Sprintf("taskMap[%s].name", k), nil), vld.SetCustomKey("ERR_VLD_TASK_NAME_INVALID"), ), ) }), // OTHER FUNCTIONS // Pass if at least one of the validations passes vld.OneOf( // List of validations ), // Pass if exact one of the validations passes vld.ExactOneOf( // List of validations ), // Pass if none of the validations passes vld.NotOf( // List of validations ), ) for _, e := range errs { detail, warnErr := e.BuildDetail() fmt.Printf("%+v\n", detail) }

Error message localization

  • Method 1: inline localization (not recommended)
 errs := Validate( NumLTE(&p.Age, 40).OnError( // Override the default template in english SetTemplate("Tuổi nhân viên phải nhỏ hơn hoặc bằng {{.Max}}"), ), ) for _, e := range errs { detail, warnErr := e.BuildDetail() fmt.Printf("%+v\n", detail) }
  • Method 2: using another localization lib (recommended)
 // Supposed you have 2 files defining error messages // In `error_messages.en`: // ERR_VLD_EMPLOYEE_AGE_TOO_BIG = "Employee {{.EmployeeName}} has age bigger than {{.Max}}" // In `error_messages.vi`: // ERR_VLD_EMPLOYEE_AGE_TOO_BIG = "Nhân viên {{.EmployeeName}} có tuổi lớn hơn {{.Max}}" errs := Validate( NumLTE(&p.Age, 40).OnError( // Custom param (the default template doesn't have this one) SetParam("EmployeeName", p.Name), // Custom key to define custom template to use SetCustomKey("ERR_VLD_EMPLOYEE_AGE_TOO_BIG"), ), ) for _, e := range errs { errKey := e.CustomKey() errParams : = e.Params() // or e.ParamsWithFormatter() errorMsg := translationFunction(errKey, errParams) // You need to provide this function fmt.Printf("%+v\n", errorMsg) }

Custom error param formatter

 errs := Validate( NumLT(&budget, 1000000).OnError( SetField("Budget", nil), ), ) // e.BuildDetail() may produce message `Budget must be less than 1000000`, // but you may want a message like: `Budget must be less than 1,000,000`. // Let's use a custom formatter errs := Validate( NumLT(&budget, 1000000).OnError( SetField("Budget", nil), SetNumParamFormatter(NewDecimalFormatFunc('.', ',', "%f")), ), )

Contributing

  • You are welcome to make pull requests for new functions and bug fixes.

License

About

Intuitive validation library for Golang

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors