xvalid

package module
v2.0.0-...-339ea1f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 2, 2024 License: MIT Imports: 7 Imported by: 0

README

xvalid

xvalid is a lightweight validation library that uses methods, and can be export as JSON.

Documentation at godoc.org

Goals

  1. Must be able to export rules so clients can consume them.
  2. Only support common rules such as those found in browsers and GUI libraries e.g. length, min, max etc.
  3. Must be easy to maintain as number of rules grows and becomes complex.

Comparison

Popular validation libraries like go-playground/validate and govalidator are great libraries but they suffer from a few problems.

  1. Since rules are defined in struct tags, errors are less easy to detect, and it becomes too difficult to read when there are many rules and many other struct tags defined. By using methods to define rules, we can rely on compilation checks and can format our code freely.
  2. They compile more regex validators than most project will ever need. By defining only common validators, we reduce unnecessary performance hit; and it is also trivial to copy/paste regex defined by other libraries.
  3. Without being able to export validation rules to client apps, developers will need to be mindful of keeping the rules in sync. By reusing validation rules, you reduce the chance of client and server validating wrongly.
  4. Rules are inflexible since they are defined with struct tags. By using methods instead of struct tags, we can dynamically define rules based on runtime data.

Examples

Define rules, validate, and export as JSON:

// Store model
type Store struct {
	Name        string `json:"name"`
	Address     string `json:"address"`
	Description string `json:"description"`
	Tax         int    `json:"tax"`
	Revenue     int    `json:"revenue"`
}

// Rules for this model.
func (store Store) Rules() xvalid.Rules {
	return xvalid.New(&store).
		Field(&store.Name, xvalid.MinLength(4).SetOptional().SetMessage("Please lengthen name to 4 characters or more"),
			xvalid.MaxLength(80).SetMessage("Please shorten name to 80 characters or less"),
			xvalid.Pattern("^[a-zA-Z0-9_]+$").SetOptional().SetMessage("Name may contain alphabets, numbers and underscores"),
			xvalid.Pattern("[a-zA-Z]").SetOptional().SetMessage("Name must contain at least 1 alphabet"),
			xvalid.FieldFunc(func(field []string, value any) xvalid.Error {
				name := value.(string)
				if name == "" {
					return nil
				}
				if name == "admin" {
					return xvalid.NewError("This name is not allowed", field)
				}
				return nil
			})).
		Field(&store.Address, xvalid.Required(), xvalid.MaxLength(120)).
		Field(&store.Description, xvalid.MaxLength(1500)).
		Field(&store.Tax, xvalid.Min(0), xvalid.Max(100)).
		Struct(xvalid.StructFunc(func(v any) xvalid.Error {
			s := v.(Store)
			if s.Revenue > 1000 && s.Tax == 0 {
				return xvalid.NewError("Tax cannot be empty if revenue is more than $1000", "tax")
			}
			return nil
		}))
}

// validate
store := Store{}
err := store.Rules().Validate(store)
if err != nil {
    panic(err)
}

// export rules as JSON
rules := store.Rules()
b, err := json.MarshalIndent(rules, "", "	")
if err != nil {
    panic(err)
}
fmt.Println(string(b))

// generate dynamic rules
runtimeRules := xvalid.New(&store).
    Field(&store.Name, xvalid.Required())
if userInput == "example" {
    runtimeRules = runtimeRules.Field(&store.Address, xvalid.MinLength(getMinLength()))
}
err := runtimeRules.Validate(store)

Custom Validators

To define your own validator, you must implement the Validator interface. For examples, see any of the validators in validators.go.

Documentation

Overview

Package xvalid is a lightweight validation library that can export rules as JSON so browsers can apply the same rules.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsEmail

func IsEmail(email string) bool

IsEmail returns true if the string is an email

Types

type EmailValidator

type EmailValidator struct {
	Validator
	// contains filtered or unexported fields
}

EmailValidator field must be a valid email address

func Email

func Email() *EmailValidator

Email field must be a valid email address

func (*EmailValidator) CanExport

func (c *EmailValidator) CanExport() bool

CanExport for this validator

func (*EmailValidator) Field

func (c *EmailValidator) Field() []string

Field of the field

func (*EmailValidator) MarshalJSON

func (c *EmailValidator) MarshalJSON() ([]byte, error)

MarshalJSON for this validator

func (*EmailValidator) SetField

func (c *EmailValidator) SetField(name ...string)

SetField of the field

func (*EmailValidator) SetMessage

func (c *EmailValidator) SetMessage(msg string) Validator

SetMessage set error message

func (*EmailValidator) SetOptional

func (c *EmailValidator) SetOptional() Validator

SetOptional don't validate if the value is zero

func (*EmailValidator) Validate

func (c *EmailValidator) Validate(value any) Error

Validate the value

type Error

type Error interface {
	Error() string
	Field() []string
}

Error when a rule is broken

func NewError

func NewError(message string, field []string) Error

NewError creates new validation error

type ErrorMap

type ErrorMap map[string]Error

ErrorMap is a map of Error

func (ErrorMap) Error

func (e ErrorMap) Error() string

Error will combine all errors into a list of sentences

func (ErrorMap) ToSlice

func (e ErrorMap) ToSlice() ErrorSlice

ToSlice converts to slice

func (ErrorMap) Unwrap

func (e ErrorMap) Unwrap() []error

Unwrap errors

type ErrorSlice

type ErrorSlice []Error

ErrorSlice is a list of Error

func (ErrorSlice) Error

func (e ErrorSlice) Error() string

Error will combine all errors into a list of sentences

func (ErrorSlice) ToMap

func (e ErrorSlice) ToMap() ErrorMap

ToMap converts to map

func (ErrorSlice) Unwrap

func (e ErrorSlice) Unwrap() []error

Unwrap errors

type FieldFuncValidator

type FieldFuncValidator struct {
	// contains filtered or unexported fields
}

FieldFuncValidator for validating with custom function

func (*FieldFuncValidator) CanExport

func (c *FieldFuncValidator) CanExport() bool

CanExport for this validator

func (*FieldFuncValidator) Field

func (c *FieldFuncValidator) Field() []string

Field of the field

func (*FieldFuncValidator) SetField

func (c *FieldFuncValidator) SetField(name ...string)

SetField of the field

func (*FieldFuncValidator) SetMessage

func (c *FieldFuncValidator) SetMessage(msg string) Validator

SetMessage set error message

func (*FieldFuncValidator) Validate

func (c *FieldFuncValidator) Validate(value any) Error

Validate the value

type MaxLengthValidator

type MaxLengthValidator struct {
	// contains filtered or unexported fields
}

MaxLengthValidator field have maximum length

func MaxLength

func MaxLength(max int64) *MaxLengthValidator

MaxLength field have maximum length

func (*MaxLengthValidator) CanExport

func (c *MaxLengthValidator) CanExport() bool

CanExport for this validator

func (*MaxLengthValidator) Field

func (c *MaxLengthValidator) Field() []string

Field of the field

func (*MaxLengthValidator) MarshalJSON

func (c *MaxLengthValidator) MarshalJSON() ([]byte, error)

MarshalJSON for this validator

func (*MaxLengthValidator) SetField

func (c *MaxLengthValidator) SetField(name ...string)

SetField of the field

func (*MaxLengthValidator) SetMessage

func (c *MaxLengthValidator) SetMessage(msg string) Validator

SetMessage set error message

func (*MaxLengthValidator) Validate

func (c *MaxLengthValidator) Validate(value any) Error

Validate the value

type MaxValidator

type MaxValidator struct {
	// contains filtered or unexported fields
}

MaxValidator field have maximum value

func Max

func Max(max int64) *MaxValidator

Max field have maximum value

func (*MaxValidator) CanExport

func (c *MaxValidator) CanExport() bool

CanExport for this validator

func (*MaxValidator) Field

func (c *MaxValidator) Field() []string

Field of the field

func (*MaxValidator) MarshalJSON

func (c *MaxValidator) MarshalJSON() ([]byte, error)

MarshalJSON for this validator

func (*MaxValidator) SetField

func (c *MaxValidator) SetField(name ...string)

SetField of the field

func (*MaxValidator) SetMessage

func (c *MaxValidator) SetMessage(msg string) Validator

SetMessage set error message

func (*MaxValidator) Validate

func (c *MaxValidator) Validate(value any) Error

Validate the value

type MinLengthValidator

type MinLengthValidator struct {
	// contains filtered or unexported fields
}

MinLengthValidator field must have minimum length

func MinLength

func MinLength(min int64) *MinLengthValidator

MinLength field must have minimum length

func (*MinLengthValidator) CanExport

func (c *MinLengthValidator) CanExport() bool

CanExport for this validator

func (*MinLengthValidator) Field

func (c *MinLengthValidator) Field() []string

Field of the field

func (*MinLengthValidator) MarshalJSON

func (c *MinLengthValidator) MarshalJSON() ([]byte, error)

MarshalJSON for this validator

func (*MinLengthValidator) SetField

func (c *MinLengthValidator) SetField(name ...string)

SetField of the field

func (*MinLengthValidator) SetMessage

func (c *MinLengthValidator) SetMessage(msg string) Validator

SetMessage set error message

func (*MinLengthValidator) SetOptional

func (c *MinLengthValidator) SetOptional() Validator

SetOptional don't validate if the value is zero

func (*MinLengthValidator) Validate

func (c *MinLengthValidator) Validate(value any) Error

Validate the value

type MinValidator

type MinValidator struct {
	// contains filtered or unexported fields
}

MinValidator field have minimum value

func Min

func Min(min int64) *MinValidator

Min field have minimum value

func (*MinValidator) CanExport

func (c *MinValidator) CanExport() bool

CanExport for this validator

func (*MinValidator) Field

func (c *MinValidator) Field() []string

Field of the field

func (*MinValidator) MarshalJSON

func (c *MinValidator) MarshalJSON() ([]byte, error)

MarshalJSON for this validator

func (*MinValidator) SetField

func (c *MinValidator) SetField(name ...string)

SetField of the field

func (*MinValidator) SetMessage

func (c *MinValidator) SetMessage(msg string) Validator

SetMessage set error message

func (*MinValidator) SetOptional

func (c *MinValidator) SetOptional() Validator

SetOptional don't validate if the value is zero

func (*MinValidator) Validate

func (c *MinValidator) Validate(value any) Error

Validate the value

type OptionsValidator

type OptionsValidator struct {
	// contains filtered or unexported fields
}

OptionsValidator for whitelisting accepted values

func (*OptionsValidator) CanExport

func (c *OptionsValidator) CanExport() bool

CanExport for this validator

func (*OptionsValidator) Field

func (c *OptionsValidator) Field() []string

Field of the field

func (*OptionsValidator) MarshalJSON

func (c *OptionsValidator) MarshalJSON() ([]byte, error)

MarshalJSON for this validator

func (*OptionsValidator) SetField

func (c *OptionsValidator) SetField(name ...string)

SetField of the field

func (*OptionsValidator) SetMessage

func (c *OptionsValidator) SetMessage(msg string) Validator

SetMessage set error message

func (*OptionsValidator) Validate

func (c *OptionsValidator) Validate(value any) Error

Validate the value

type PatternValidator

type PatternValidator struct {
	// contains filtered or unexported fields
}

PatternValidator field must match regexp

func Pattern

func Pattern(pattern string) *PatternValidator

Pattern field must match regexp

func (*PatternValidator) CanExport

func (c *PatternValidator) CanExport() bool

CanExport for this validator

func (*PatternValidator) Field

func (c *PatternValidator) Field() []string

Field of the field

func (*PatternValidator) MarshalJSON

func (c *PatternValidator) MarshalJSON() ([]byte, error)

MarshalJSON for this validator

func (*PatternValidator) SetField

func (c *PatternValidator) SetField(name ...string)

SetField of the field

func (*PatternValidator) SetMessage

func (c *PatternValidator) SetMessage(msg string) Validator

SetMessage set error message

func (*PatternValidator) SetOptional

func (c *PatternValidator) SetOptional() Validator

SetOptional don't validate if the value is zero

func (*PatternValidator) Validate

func (c *PatternValidator) Validate(value any) Error

Validate the value

type RequiredValidator

type RequiredValidator struct {
	// contains filtered or unexported fields
}

RequiredValidator field must not be zero

func Required

func Required() *RequiredValidator

Required fields must not be zero

func (*RequiredValidator) CanExport

func (c *RequiredValidator) CanExport() bool

CanExport for this validator

func (*RequiredValidator) Field

func (c *RequiredValidator) Field() []string

Field of the field

func (*RequiredValidator) MarshalJSON

func (c *RequiredValidator) MarshalJSON() ([]byte, error)

MarshalJSON for this validator

func (*RequiredValidator) SetField

func (c *RequiredValidator) SetField(field ...string)

SetField of the field

func (*RequiredValidator) SetMessage

func (c *RequiredValidator) SetMessage(msg string) Validator

SetMessage set error message

func (*RequiredValidator) Validate

func (c *RequiredValidator) Validate(value any) Error

Validate the value

type Rules

type Rules struct {
	// contains filtered or unexported fields
}

Rules for creating a chain of rules for validating a struct

func New

func New(structPtr any) Rules

New rule chain

func (Rules) Field

func (r Rules) Field(fieldPtr any, validators ...Validator) Rules

Field adds validators for a field

func (Rules) MarshalJSON

func (r Rules) MarshalJSON() ([]byte, error)

func (Rules) Struct

func (r Rules) Struct(validators ...Validator) Rules

Struct adds validators for the struct

func (Rules) Validate

func (r Rules) Validate(subject any) ErrorSlice

Validate a struct and return Errors

func (Rules) Validators

func (r Rules) Validators() []Validator

Validators for this chain

type StructFuncValidator

type StructFuncValidator struct {
	// contains filtered or unexported fields
}

StructFuncValidator validate struct with custom function. Add to rules with .Struct().

func (*StructFuncValidator) CanExport

func (c *StructFuncValidator) CanExport() bool

CanExport for this validator

func (*StructFuncValidator) Field

func (c *StructFuncValidator) Field() []string

Field of the field

func (*StructFuncValidator) SetField

func (c *StructFuncValidator) SetField(name ...string)

SetField of the field

func (*StructFuncValidator) SetMessage

func (c *StructFuncValidator) SetMessage(msg string) Validator

SetMessage set error message

func (*StructFuncValidator) Validate

func (c *StructFuncValidator) Validate(value any) Error

Validate the value

type Validator

type Validator interface {
	SetField(...string)
	Field() []string
	CanExport() bool
	SetMessage(string) Validator
	Validate(any) Error
}

Validator to implement a rule

func FieldFunc

func FieldFunc(f func([]string, any) Error) Validator

FieldFunc for validating with custom function

func Options

func Options(options ...any) Validator

Options for whitelisting accepted values

func StructFunc

func StructFunc(f func(any) Error) Validator

StructFunc validate struct with custom function

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL