kensho

package module
v0.0.0-...-e12c452 Latest Latest
Warning

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

Go to latest
Published: Oct 2, 2019 License: MIT Imports: 12 Imported by: 3

README

Kenshō - A Go validator

Build Status Coverage Status Go Report Card

A Work in progress project so the master branch might change in the future and BC breaks some part or change some behaviors.

A simple Go library for validation, but gives the possibility to validate deeply, collections, any field type of struct by following tag or file.

TODO

  • More docs/examples
  • More tests
  • Add validators

Features

  • Struct validation
  • Able to add custom constraints
  • Validator argument
  • Configuration from a file (ex: json)
  • Deep validation
  • List of struct validation
  • Translation

Installation

go get github.com/maxperrimond/kensho

Usage

Here some code as an example:

package main

import (
	"fmt"

	"github.com/maxperrimond/kensho"
)

type Group struct {
	Name  string  `valid:"required"`
	Users []*User `valid:"valid"` // Ask to valid users if there is some
}

type User struct {
	Email     string `valid:"required,email"`
	FirstName string `valid:"required,min=2,max=64"`
	LastName  string `valid:"required,min=2,max=64"`
}

func main() {
	// Simple struct
	user := &User{
		Email:     "foo.bar@example.com",
		FirstName: "foo",
		LastName:  "bar",
	}

	// Validate user
	ok, violations, _ := kensho.Validate(user)

	fmt.Printf("Result: %t\n", ok)
	fmt.Println(violations)

	user.Email = "this is not an email"
	user.FirstName = ""

	// Validate user after inserting bad data
	ok, violations, _ = kensho.Validate(user)

	fmt.Printf("Result: %t\n", ok)
	fmt.Println(violations)

	users := []*User{
		{
			Email:     "john@example.com",
			FirstName: "john",
			LastName:  "bar",
		},
		{
			Email:     "pierre@example.com",
			FirstName: "pierre",
			LastName:  "bar",
		},
	}

	// Validate collection of users
	ok, violations, _ = kensho.Validate(users)

	fmt.Printf("Result: %t\n", ok)
	fmt.Println(violations)

	// Nested struct
	group := &Group{
		Name:  "foo",
		Users: append(users, user), // With the bad user
	}

	// Validate the group
	ok, violations, _ = kensho.Validate(group)

	fmt.Printf("Result: %t\n", ok)
	fmt.Println(violations)
}
Available constraints
Tag Arg Description
valid Validate nested struct
string Check is string
struct Check is struct
required Is required
length int Match length
min int Match min length
max int Match max length
regex string (regex pattern) Match pattern
email Match email
uuid Match UUID
iso3166 optional: num, alpha3, alpha2 (default) Match country code based on IS03166

And more to come

Custom constraint
package main

import (
	"context"
	"errors"

	"github.com/maxperrimond/kensho"
)

// Define your constraint
func poneyConstraint(ctx *kensho.ValidationContext) error {
	if ctx.Value() != "poney" {
		ctx.BuildViolation("invalid_poney", nil).AddViolation()
	}

	return nil
}

func init() {
	// add it with the tag of your choice
    kensho.AddConstraint("poney", poneyConstraint)
}

Note: If you use an existent tag, it will override it.

Context

You can pass a context during validation so it can be accessible in constraints:

ok, violations, err := kensho.ValidateWithContext(ctx, subject)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddConstraint

func AddConstraint(name string, constraint Constraint)

func AddParser

func AddParser(extension string, parser Parser)

func ColorHexConstraint

func ColorHexConstraint(ctx *ValidationContext) error

func EmailConstraint

func EmailConstraint(ctx *ValidationContext) error

func ISO3166Constraint

func ISO3166Constraint(ctx *ValidationContext) error

func ISO639Constraint

func ISO639Constraint(ctx *ValidationContext) error

func LengthConstraint

func LengthConstraint(ctx *ValidationContext) error

func LoadFiles

func LoadFiles(patterns ...string) error

func MaxConstraint

func MaxConstraint(ctx *ValidationContext) error

func MinConstraint

func MinConstraint(ctx *ValidationContext) error

func RegexConstraint

func RegexConstraint(ctx *ValidationContext) error

func RequiredConstraint

func RequiredConstraint(ctx *ValidationContext) error

func StringConstraint

func StringConstraint(ctx *ValidationContext) error

func StructConstraint

func StructConstraint(ctx *ValidationContext) error

func UUIDConstraint

func UUIDConstraint(ctx *ValidationContext) error

Types

type Constraint

type Constraint func(ctx *ValidationContext) error

type ConstraintArgs

type ConstraintArgs struct {
	Root    interface{}
	Subject interface{}
	Value   interface{}
	Arg     interface{}
}

type ConstraintMetadata

type ConstraintMetadata struct {
	Tag        string
	Constraint Constraint
	Arg        interface{}
}

type CustomConstraint

type CustomConstraint struct {
	Name       string
	Constraint Constraint
}

func NewCustomConstraint

func NewCustomConstraint(name string, constraint Constraint) CustomConstraint

type ErrorTranslator

type ErrorTranslator func(key string, parameters map[string]interface{}) string
var TranslateError ErrorTranslator = func(key string, parameters map[string]interface{}) string {
	return key
}

type FieldMetadata

type FieldMetadata struct {
	FieldName   string
	Constraints []*ConstraintMetadata
}

type Parser

type Parser func(config string) ([]*StructMetadata, error)

type StructMetadata

type StructMetadata struct {
	StructName string
	Fields     map[string]*FieldMetadata
}

type ValidationContext

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

func (*ValidationContext) Arg

func (ctx *ValidationContext) Arg() interface{}

func (*ValidationContext) BuildViolation

func (ctx *ValidationContext) BuildViolation(error string, parameters map[string]interface{}) *violationBuilder

func (*ValidationContext) Ctx

func (ctx *ValidationContext) Ctx() context.Context

func (*ValidationContext) Path

func (ctx *ValidationContext) Path() string

func (*ValidationContext) Root

func (ctx *ValidationContext) Root() interface{}

func (*ValidationContext) Subject

func (ctx *ValidationContext) Subject() interface{}

func (*ValidationContext) Value

func (ctx *ValidationContext) Value() interface{}

func (*ValidationContext) ViolationList

func (ctx *ValidationContext) ViolationList() ViolationList

func (*ValidationContext) WithArg

func (ctx *ValidationContext) WithArg(arg interface{}) *ValidationContext

func (*ValidationContext) WithValue

func (ctx *ValidationContext) WithValue(value interface{}) *ValidationContext

type Validator

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

func NewValidator

func NewValidator(customConstraints ...CustomConstraint) *Validator

func (*Validator) AddConstraint

func (validator *Validator) AddConstraint(name string, constraint Constraint)

func (*Validator) AddParser

func (validator *Validator) AddParser(extension string, parser Parser)

func (*Validator) LoadFiles

func (validator *Validator) LoadFiles(patterns ...string) error

func (*Validator) Validate

func (validator *Validator) Validate(subject interface{}) (bool, ViolationList, error)

func (*Validator) ValidateWithContext

func (validator *Validator) ValidateWithContext(ctx context.Context, subject interface{}) (bool, ViolationList, error)

type Violation

type Violation struct {
	Path       string                 `json:"path"`
	Error      string                 `json:"error"`
	Message    string                 `json:"message,omitempty"`
	Parameters map[string]interface{} `json:"parameters,omitempty"`
	Code       string                 `json:"code,omitempty"`
}

type ViolationList

type ViolationList []*Violation

func Validate

func Validate(subject interface{}) (bool, ViolationList, error)

func ValidateWithContext

func ValidateWithContext(ctx context.Context, subject interface{}) (bool, ViolationList, error)

func (ViolationList) String

func (violations ViolationList) String() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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