validation

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Dec 18, 2023 License: Apache-2.0 Imports: 9 Imported by: 1

README

Go Validation Build Status GoDoc License

Provide a validation framework based on the built rule, supporting Go1.16+.

Install

$ go get -u github.com/xgfone/go-validation

Example

For registering the validator and validating whether a value is valid, See Builder.

package main

import "github.com/xgfone/go-validation"

func main() {
	// Validate whether an integer is in [min, max].
	validation.Validate(123, `min(1) && max(200)`) // => <nil>
	validation.Validate(456, `min(1) && max(200)`) // => an error
	validation.Validate(123, `ranger(1, 200)`)     // => <nil>
	validation.Validate(456, `ranger(1, 200)`)     // => an error

	// Validate whether an string is one of a string list.
	validation.Validate("a", `oneof("a", "b", "c")`) // => <nil>
	validation.Validate("d", `oneof("a", "b", "c")`) // => an error

	// Validate whether an string is an integer string that can be parsed to an integer.
	validation.Validate("123", `isinteger`)  // => <nil>
	validation.Validate("+123", `isinteger`) // => <nil>
	validation.Validate("-123", `isinteger`) // => <nil>
	validation.Validate("12.3", `isinteger`) // => an error
	validation.Validate("abc", `isinteger`)  // => an error

	// Validate whether an string is an float string that can be parsed to an float.
	validation.Validate("123", `isnumber`)  // => <nil>
	validation.Validate("12.3", `isnumber`) // => <nil>
	validation.Validate("-1.2", `isnumber`) // => <nil>
	validation.Validate("123.", `isnumber`) // => <nil>
	validation.Validate(".123", `isnumber`) // => <nil>
	validation.Validate("abc", `isnumber`)  // => an error

	// Validate whether a value is ZERO.
	validation.Validate(0, `zero`)     // => <nil>
	validation.Validate(1, `zero`)     // => an error
	validation.Validate("", `zero`)    // => <nil>
	validation.Validate("0", `zero`)   // => an error
	validation.Validate(false, `zero`) // => <nil>
	validation.Validate(true, `zero`)  // => an error
	var p *int
	validation.Validate(p, `zero`) // => <nil>
	p = new(int)
	validation.Validate(p, `zero`) // => an error

	// Validate whether a value is not ZERO.
	validation.Validate(0, `required`)     // => an error
	validation.Validate(1, `required`)     // => <nil>
	validation.Validate("", `required`)    // => an error
	validation.Validate("0", `required`)   // => <nil>
	validation.Validate(false, `required`) // => an error
	validation.Validate(true, `required`)  // => <nil>
	p = nil
	validation.Validate(p, `required`) // => an error
	p = new(int)
	validation.Validate(p, `required`) // => <nil>

	// Validate whether a slice/array is valid.
	validation.Validate([]int{1, 2}, `array(min(1), max(10))`)  // slice, => <nil>
	validation.Validate([3]int{1, 2}, `array(min(1), max(10))`) // array, => an error

	// Validate whether a map(key, value or key-value) is valid.
	maps := map[int]string{0: "a", 1: "b"}
	validation.Validate(maps, `mapk(min(0), max(10))`) // => <nil>
	validation.Validate(maps, `mapk(min(1), max(10))`) // => an error
	validation.Validate(maps, `mapv(oneof("a", "b"))`) // => <nil>
	validation.Validate(maps, `mapv(oneof("a", "c"))`) // => an error

// For the validation rule, it support the multi-level AND/OR. For example,
// - "min(100) && max(200)"
//    => A value, such as integer or length of string/slice, in [100, 200] is valid.
// - "min(200) || max(100)"
//    => A value, such as integer or length of string/slice, in (-∞, 100] or [200, +∞) is valid.
// - "(min(200) || max(100)) && required)"
//    => Same as "min(200) || max(100)", but also cannot be ZERO.
}

Documentation

Overview

Package validation provides a validation framework based on the built rule.

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultBuilder = NewBuilder()

DefaultBuilder is the global default validation rule builder, which will register some default validator building functions. See RegisterDefaults.

Functions

func RegisterDefaultsForBuilder

func RegisterDefaultsForBuilder(b *Builder)

RegisterDefaultsForBuilder registers the default symbols and validators building functions into the builder.

The registered default symbols:

timelayout: 15:04:05
datelayout: 2006-01-02
datetimelayout: 2006-01-02 15:04:05

The Signature of the registered validator functions as follow:

ip() or ip
mac() or mac
url() or url
addr() or addr
cidr() or cidr
zero() or zero
isinteger() or isinteger
isnumber() or isnumber
duration() or duration
required() or required
structure() or structure
exp(base, startExp, endExp int)
min(float64)
max(float64)
ranger(min, max float64)
time(formatLayout string)
oneof(...string)
array(...Validator)
mapkv(...Validator)
mapk(...Validator)
mapv(...Validator)
timeformat() or timeformat => time(timelayout)
dateformat() or dateformat => time(datelayout)
datetimeformat() or datetimeformat => time(datetimelayout)

func RegisterStringValidatorsForBuilder

func RegisterStringValidatorsForBuilder(b *Builder)

RegisterStringValidatorsForBuilder registers some string validators, that's, the value is a specific string.

isascii
isalpha
isalphanumeric
isbase64
iscrc32
iscrc64
isdnsname
isdatauri
ise164
isemail
isexistingemail
isfloat
ishexadecimal
ishexcolor
ishost
isimei
isimsi
isipv4
isipv6
isisbn10
isisbn13
isint
isjson
islatitude
islongitude
islowercase
ismd4
ismd5
ismagneturi
ismongoid
isprintableascii
isrfc3390
isrfc3390withoutzone
isrgbcolor
isrequesturi
isrequesturl
isripemd128
isripemd160
issha1
issha256
issha3224
issha3256
issha3384
issha3512
issha384
issha512
isssn
issemver
istiger128
istiger160
istiger192
isulid
isurl
isutfdigit
isutfletter
isutfletternumeric
isutfnumeric
isuuid
isuuid3
isuuid4
isuuid5
isuppercase

func RegisterValidatorFunc

func RegisterValidatorFunc(name string, f validator.ValidateFunc)

RegisterValidatorFunc is equal to DefaultBuilder.RegisterValidatorFunc(name, f).

func RegisterValidatorOneof

func RegisterValidatorOneof(name string, values ...string)

RegisterValidatorOneof is equal to DefaultBuilder.RegisterValidatorOneof(name,values...).

func Validate

func Validate(v interface{}, rule string) error

Validate is equal to DefaultBuilder.Validate(v, rule).

Types

type Builder

type Builder struct {
	// Symbols is used to define the global symbols,
	// which is used by the default of GetIdentifier.
	Symbols map[string]interface{}

	*predicate.Builder
	// contains filtered or unexported fields
}

Builder is used to build the validator based on the rule.

Example
////// Register the validator building functions.
// RegisterFunction(NewFunctionWithOneFloat("min", validator.Min))
// RegisterFunction(NewFunctionWithOneFloat("max", validator.Max))
// RegisterFunction(NewFunctionWithStrings("oneof", validator.OneOf))
// RegisterFunction(NewFunctionWithValidators("array", validator.Array))
// RegisterFunction(NewFunctionWithValidators("mapk", validator.MapK))
// RegisterFunction(NewFunctionWithValidators("mapv", validator.MapV))
// RegisterFunction(NewFunctionWithValidators("mapkv", validator.MapKV))

////// Register the validator building function based on the bool validation.
// isZero := func(i interface{}) bool { return reflect.ValueOf(i).IsZero() }
// RegisterValidatorFuncBool("zero", isZero, fmt.Errorf("the value is expected to be zero"))
// RegisterValidatorFunc("structure", ValidateStruct)

// Add the global symbols.
DefaultBuilder.RegisterSymbol("v1", "a")
DefaultBuilder.RegisterSymbol("v2", "b")

// Example 1: function mode
fmt.Println("\n--- Function Mode ---")

c := NewContext()
err := DefaultBuilder.Build(c, "min(1) && max(10)")
if err != nil {
	fmt.Println(err)
	return
}

validator := c.Validator()
fmt.Printf("Rule: %s\n", validator.String())
fmt.Println(validator.Validate(0))
fmt.Println(validator.Validate(1))
fmt.Println(validator.Validate(5))
fmt.Println(validator.Validate(10))
fmt.Println(validator.Validate(11))

// Example 2: Identifier+operator mode
fmt.Println("\n--- Identifier+Operator Mode ---")

c = NewContext()
err = DefaultBuilder.Build(c, "zero || (min==3 && max==10)")
if err != nil {
	fmt.Println(err)
	return
}

validator = c.Validator()
fmt.Printf("Rule: %s\n", validator.String())
fmt.Println(validator.Validate(""))
fmt.Println(validator.Validate("a"))
fmt.Println(validator.Validate("abc"))
fmt.Println(validator.Validate("abcdefghijklmn"))

// Example 3: The simpler validation way
const rule1 = "zero || (min==3 && max==10)"
fmt.Println(Validate("", rule1))
fmt.Println(Validate("a", rule1))
fmt.Println(Validate("abc", rule1))
fmt.Println(Validate("abcdefghijklmn", rule1))

// Example 4: Validate the array
fmt.Println("\n--- Array ---")
const rule2 = "zero || array(min(1), max(10))"
fmt.Println(Validate([]int{1, 2, 3}, rule2))
fmt.Println(Validate([]string{"a", "bc", "def"}, rule2))
fmt.Println(Validate([]int{}, rule2))
fmt.Println(Validate([]int{0, 1, 2}, rule2))
fmt.Println(Validate([]string{"a", "bc", ""}, rule2))

// Example 5: Valiate the map
fmt.Println("\n--- Map ---")
const rule3 = `mapk(min(1) && max(3))`
fmt.Println(Validate(map[string]int{"a": 123}, rule3))
fmt.Println(Validate(map[string]int8{"abcd": 123}, rule3))

const rule4 = `mapv(min==10 && max==100)`
fmt.Println(DefaultBuilder.BuildValidator(rule4))
fmt.Println(Validate(map[string]int16{"a": 10}, rule4))
fmt.Println(Validate(map[string]int32{"abcd": 123}, rule4))

// Example 6: Others
fmt.Println("\n--- Others ---")
const oneof = `oneof(v1, v2, "c")`
fmt.Println(Validate("a", oneof))
fmt.Println(Validate("x", oneof))
Output:


--- Function Mode ---
Rule: (min(1) && max(10))
the integer is less than 1
<nil>
<nil>
<nil>
the integer is greater than 10

--- Identifier+Operator Mode ---
Rule: (zero || (min(3) && max(10)))
<nil>
the string length is less than 3
<nil>
the string length is greater than 10
<nil>
the string length is less than 3
<nil>
the string length is greater than 10

--- Array ---
<nil>
<nil>
<nil>
0th element is invalid: the integer is less than 1
2th element is invalid: the string length is less than 1

--- Map ---
<nil>
map key 'abcd' is invalid: the string length is greater than 3
mapv(min(10) && max(100)) <nil>
<nil>
map value '123' is invalid: the integer is greater than 100

--- Others ---
<nil>
the string 'x' is not one of [a b c]

func NewBuilder

func NewBuilder() *Builder

NewBuilder returns a new validation rule builder.

func (*Builder) Build

func (b *Builder) Build(c *Context, rule string) error

Build parses and builds the validation rule into the context.

func (*Builder) BuildValidator

func (b *Builder) BuildValidator(rule string) (validator.Validator, error)

BuildValidator builds a validator from the validation rule.

If the rule has been built, returns it from the caches.

func (*Builder) RegisterFunction

func (b *Builder) RegisterFunction(function Function)

RegisterFunction registers the builder function.

If the function has existed, reset it to the new function.

func (*Builder) RegisterSymbol

func (b *Builder) RegisterSymbol(name string, value interface{})

RegisterSymbol registers the symbol with the name and value.

func (*Builder) RegisterSymbolNames

func (b *Builder) RegisterSymbolNames(names ...string)

RegisterSymbolNames registers a set of symbols with the names, the value of whose are equal to their name.

func (*Builder) RegisterValidatorFunc

func (b *Builder) RegisterValidatorFunc(name string, f validator.ValidateFunc)

RegisterValidatorFunc is a convenient method to treat the validation function with the name as a builder function to be registered, which is equal to

b.RegisterFunction(ValidatorFunction(name, validator.NewValidator(name, f)))

func (*Builder) RegisterValidatorFuncBool

func (b *Builder) RegisterValidatorFuncBool(name string, f func(interface{}) bool, err error)

RegisterValidatorFuncBool is a convenient method to treat the bool validation function with the name as a builder function to be registered, which is equal to

b.RegisterValidatorFunc(name, validator.BoolValidateFunc(f, err))

func (*Builder) RegisterValidatorFuncBoolString

func (b *Builder) RegisterValidatorFuncBoolString(name string, f func(string) bool, err error)

RegisterValidatorFuncBoolString is a convenient method to treat the string bool validation function with the name as a builder function to be registered, which is equal to

b.RegisterValidatorFunc(name, validator.StringBoolValidateFunc(f, err))

func (*Builder) RegisterValidatorOneof

func (b *Builder) RegisterValidatorOneof(name string, values ...string)

RegisterValidatorOneof is a convenient method to register a oneof validator as the builder Function, which is equal to

b.RegisterFunction(ValidatorFunction(name, validators.OneOfWithName(name, values...)))
Example
const rule = "isnumber"
numbers := []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}

builder := NewBuilder()
builder.RegisterValidatorOneof(rule, numbers...)

// Validate the value and print the result.
fmt.Println(builder.Validate("0", rule))
fmt.Println(builder.Validate("9", rule))
fmt.Println(builder.Validate("a", rule))
Output:

<nil>
<nil>
the string 'a' is not one of [0 1 2 3 4 5 6 7 8 9]

func (*Builder) Validate

func (b *Builder) Validate(v interface{}, rule string) (err error)

Validate validates whether the value v is valid by the rule.

If failing to build the rule to the validator, panic with the error.

type Context

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

Context is a builder context to manage the built validators.

func NewContext

func NewContext() *Context

NewContext returns a new builder context.

func (*Context) And

func (c *Context) And(bc predicate.BuilderContext)

And implements the interface predicate.BuidlerContext.

func (*Context) AppendValidators

func (c *Context) AppendValidators(validators ...validator.Validator)

AppendValidators appends the new validators into the context.

The method is used by the validator building function.

func (*Context) New

func (c *Context) New() predicate.BuilderContext

New implements the interface predicate.BuidlerContext.

func (*Context) Not

Not implements the interface predicate.BuidlerContext.

func (*Context) Or

func (c *Context) Or(bc predicate.BuilderContext)

Or implements the interface predicate.BuidlerContext.

func (*Context) Validator

func (c *Context) Validator() validator.Validator

Validator returns the inner validators as And Validator.

func (*Context) Validators

func (c *Context) Validators() []validator.Validator

Validators returns all the inner validators.

type Function

type Function interface {
	Call(c *Context, args ...interface{}) error
	Name() string
}

Function is called by the builder to parse and build the validator.

func NewFunction

func NewFunction(name string, call func(*Context, ...interface{}) error) Function

NewFunction returns a new Function.

func NewFunctionWithFloats

func NewFunctionWithFloats(name string, newf func(...float64) validator.Validator) Function

NewFunctionWithFloats returns a new Function which parses and builds the validator with any float64 arguments.

func NewFunctionWithOneFloat

func NewFunctionWithOneFloat(name string, newf func(float64) validator.Validator) Function

NewFunctionWithOneFloat returns a new Function which parses and builds the validator with only one float64 argument.

func NewFunctionWithOneString

func NewFunctionWithOneString(name string, newf func(string) validator.Validator) Function

NewFunctionWithOneString returns a new Function which parses and builds the validator with only one string argument.

func NewFunctionWithStrings

func NewFunctionWithStrings(name string, newf func(...string) validator.Validator) Function

NewFunctionWithStrings returns a new Function which parses and builds the validator with any string arguments.

func NewFunctionWithThreeInts

func NewFunctionWithThreeInts(name string, newf func(int, int, int) validator.Validator) Function

NewFunctionWithThreeInts returns a new Function which parses and builds the validator with only three int arguments.

func NewFunctionWithTwoFloats

func NewFunctionWithTwoFloats(name string, newf func(float64, float64) validator.Validator) Function

NewFunctionWithTwoFloats returns a new Function which parses and builds the validator with only two float64 arguments.

func NewFunctionWithValidators

func NewFunctionWithValidators(name string, newf func(...validator.Validator) validator.Validator) Function

NewFunctionWithValidators returns a new Function which parses and builds the validator with any Validator arguments but at least one.

Notice: the parsed validators is composed to a new Valiator by And.

func NewFunctionWithoutArgs

func NewFunctionWithoutArgs(name string, newf func() validator.Validator) Function

NewFunctionWithoutArgs returns a new Function which parses and builds the validator without any arguments.

func ValidatorFunction

func ValidatorFunction(name string, v validator.Validator) Function

ValidatorFunction converts a validator to a Function with the name, which is equal to

NewFunctionWithoutArgs(name, func() validator.Validator { return v })
Example
// New a validator "oneof".
ss := []string{"one", "two", "three"}
desc := fmt.Sprintf(`oneof("%s")`, strings.Join(ss, `", "`))
oneof := validator.NewValidator(desc, func(i interface{}) error {
	if s, ok := i.(string); ok {
		for _, _s := range ss {
			if _s == s {
				return nil
			}
		}
		return fmt.Errorf("the string '%s' is not one of %v", s, ss)
	}
	return fmt.Errorf("unsupported type '%T'", i)
})

// Register the "oneof" validator as a Function.
rule := "oneof"
builder := NewBuilder()
builder.RegisterFunction(ValidatorFunction(rule, oneof))

// Print the validator description.
fmt.Println(oneof.String())

// Validate the value and print the result.
fmt.Println(builder.Validate("one", rule))
fmt.Println(builder.Validate("two", rule))
fmt.Println(builder.Validate("three", rule))
fmt.Println(builder.Validate("four", rule))
Output:

oneof("one", "two", "three")
<nil>
<nil>
<nil>
the string 'four' is not one of [one two three]

Directories

Path Synopsis
Package validator provides a validator interface.
Package validator provides a validator interface.
str
Package str is ported from github.com/asaskevich/govalidator@v11.0.1 because govalidator does not conform with Go Module v2+.
Package str is ported from github.com/asaskevich/govalidator@v11.0.1 because govalidator does not conform with Go Module v2+.
validators
Package validators provides some common validators.
Package validators provides some common validators.

Jump to

Keyboard shortcuts

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