Skip to content

A package that generates validation functions for structs based on tags to avoid using reflection

License

Notifications You must be signed in to change notification settings

cscoding21/csval

Repository files navigation

       
   

CSVal

CSVal is a Golang package that allows the developer to define object validation rules using struct tags, but without having to rely on runtime reflection, which can have suboptimal performance. If reflection is not a problem...Go Playground Validator is an excellent alternative.

CSVal consists of the following components:

  • generator: a package that views target code and generated corresponding validation source.
  • validator: a library of common validation rules that can be applied to the fields within structs.
  • runner: an executable that runs via go generate and leverages the generator package against the developer's code

Usage

To use CSVal, add the csval tag with a comma-separated list of rules to your struct's field definitions. For example...given the file data.go:

//go:generate csval

package tests

// FooStruct is a sample struct to be validated
type FooStruct struct {
    Name        string       `csval:"req"`
    Email       string       `csval:"req,email"`
    Password    string       `csval:"min(3),max(11)"`
    ConfirmPass string       `csval:"req,equals(Password)"`
    Age         int          `csval:"min(18),max(65)"`
    Sub         BarSubStruct `csval:"obj"`
}

// BarSubStruct is a sample struct to be validated
type BarSubStruct struct {
    IP   string `csval:"req,ip"`
    Port int
}

The above struct is annotated with csval tags that define validation rules for the object. When run, the generator will create a new file in the same package called data_csval.gen.go. The new file will contain a Validate method with the FooStruct struct as a receiver as follows.

func (obj *FooStruct) Validate() validate.ValidationResult {
    result := validate.NewSuccessValidationResult()

    // ---Field: Name
    result.Append(validate.IsNotEmpty("Name", obj.Name))

    // ---Field: Email
    result.Append(validate.IsNotEmpty("Email", obj.Email))
    result.Append(validate.IsEmail("Email", obj.Email))

    // ---Field: Password
    result.Append(validate.IsLengthGreaterThan("Password", obj.Password, 3))
    result.Append(validate.IsLengthLessThan("Password", obj.Password, 11))

    // ---Field: ConfirmPass
    result.Append(validate.IsNotEmpty("ConfirmPass", obj.ConfirmPass))
    result.Append(validate.IsEqualTo("ConfirmPass:Password", obj.ConfirmPass, obj.Password))

    // ---Field: Age
    result.Append(validate.IsGreaterThan("Age", obj.Age, 18))
    result.Append(validate.IsLessThan("Age", obj.Age, 65))

    // ---Field: Sub
    result.Append(obj.Sub.Validate())

    return result
}

The ValidationResult object contains a pass/fail status and a list of error messages if applicable.

Installation

To use CSVal within your Go project, there are two installation steps. The first is to add the package:

go get github.com/cscoding21/csval

Additionally, the runner needs to be installed on the target machine. This executes the generator when go generate is invoked.

go install github.com/cscoding21/csval

Usage

To use CSVal, annotate the struct fields with the csval tag. The following annotations are supported:

Annotation Description
req The field is required
email The field must be a valid email address
ip The field must be a valid IP address
url The field must be greater than or equal to x
min(x) If the field type is string, the length must be greater than or equal to x. If the type is numeric, the value must be greater than or equal to x
max(x) If the field type is string, the length must be less than or equal to x. If the type is numeric, the value must be less than or equal to x
equals(x) The field must be equal to the value of another field, represented by x
regex(x) The field must satisfy the regular expression represented by x
validate The field will have its own Validate function called. This is for fields of a type that has CS validation rules

Post code generation, testing the validity of an object is as simple as calling the Validate method. For example...

s := &FooStruct{}
result := s.Validate()
if !result.Pass {
    for _, err := range result.Messages {
        fmt.Println(err.Field, err.Message)
    }
}

About

A package that generates validation functions for structs based on tags to avoid using reflection

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •