golidator

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jan 6, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

README

Package validator

Type-safe data validation in Go, Zod/Joi style (code-based schemas), with defaults, opt-in coercion, errors with paths, and support for validating structs and JSON ([]byte / json.RawMessage).

What it does (no magic)

  • Code-based schemas: compose rules using methods (Text().Min(3), etc).
  • Single pass: Validate handles default → parse/coerce → validation and returns the final type.
  • Presence: differentiates between missing (not provided) and null (explicitly null).
  • Error paths: user.name, items[0], meta["a-b"].
  • FailFast / MaxIssues via options.
  • Ready-to-use common validations (e.g., email, uuid, ip, base64, semver, file/dir/image, etc).

Installation

go get github.com/leandroluk/go/validator

Quick Start

Primitives
package main

import (
	"fmt"

	"github.com/leandroluk/go/validator"
)

func main() {
	nameSchema := validator.Text().
		Required().
		Min(3).
		Max(50)

	value, err := nameSchema.Validate("Jo")
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(value)
}
Validate[T] (struct + registry)

Validate[T] looks up a compatible schema for T in the registry.

package main

import (
	"fmt"

	"github.com/leandroluk/go/validator"
)

type User struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

func main() {
	validator.Object(func(u *User, s *validator.ObjectSchema[User]) {
		s.Field(&u.Name, func(ctx *validator.Context, v any) (any, bool) {
			return validator.Text().Required().Min(3).ValidateAny(v, ctx.Options)
		})
		s.Field(&u.Age, func(ctx *validator.Context, v any) (any, bool) {
			return validator.NumberSchemaOf[int]().Min(0).Max(130).ValidateAny(v, ctx.Options)
		})
	})

	out, err := validator.Validate[User]([]byte(`{"name":"John","age":30}`))
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Printf("%+v\n", out)
}
Defaults

By default, defaults apply to both missing and null. To disable for null, use WithDefaultOnNull(false).

ageSchema := validator.NumberSchemaOf[int]().Default(18).Min(0).Max(130)

a, _ := ageSchema.Validate(nil)
b, _ := ageSchema.Validate(nil, validator.WithDefaultOnNull(false))
Coerce (opt-in) + flags

WithCoerce(true) enables base coercion. More "aggressive" coercions are only enabled with specific flags.

Common examples (depend on the schema):

  • WithCoerceTrimSpace(true) (e.g., " 12 ").
  • WithCoerceNumberUnderscore(true) (e.g., "1_000").
  • WithCoerceDurationSeconds(true) / WithCoerceDurationMilliseconds(true) (e.g., 5 becomes 5s/5ms).
n, err := validator.NumberSchemaOf[int]().
	Validate(
		" 1_000 ",
		validator.WithCoerce(true),
		validator.WithCoerceTrimSpace(true),
		validator.WithCoerceNumberUnderscore(true),
	)
OmitZero (similar to omitempty)

When WithOmitZero(true) is active, "zero" values in structs/maps are omitted during reflected input.

out, err := validator.Validate[User](user, validator.WithOmitZero(true))

Available Schemas (summary)

  • text: required, isDefault, len/min/max, equals, pattern, oneOf, email/url/uri/urn, uuid, ip, base64, semver/cve, filesystem (file/dir/image), hashes etc.
  • number: required, min/max, default, oneOf, coerce(stringNumber + flags)
  • boolean: required, default, coerce(string|0/1)
  • date: required, min/max, default, parse(layouts+location), coerce(optional)
  • duration: required, min/max, default, parse(durationString), number = nanos (AST), Go number = only with seconds/millis flags
  • array: required, min/max, default, items, unique, coerce(singleton)
  • record: required, min/max, default, keys, values, unique
  • object: required, default, fields (resolve pointer + json tag), rules, StructOnly/NoStructLevel, cross-field conditions
  • combinator: AnyOf, OneOf

Full list and examples: docs/schemas.md.

Options (global)

  • WithFailFast(bool)
  • WithMaxIssues(int)
  • WithDefaultOnNull(bool) (default: true)
  • WithCoerce(bool)
  • WithOmitZero(bool)
  • WithTimeLocation(*time.Location)
  • WithDateLayouts(...string)
  • coercion flags (if available in your build): trim space, underscore, unix seconds/millis, etc

Errors

When validation fails, it returns a ValidationError (in internal/issues) containing a list of issues:

  • issue.code (e.g., text.min, number.type)
  • issue.message (e.g., too short, expected number)
  • issue.path (e.g., user.name, items[0], meta["a-b"])
  • issue.meta (e.g., expected, actual, min, max, value, error)

Docs

  • Migration from go-playground/validator (tags → schema): docs/migration-go-playground.md
  • Schema reference: docs/schemas.md

Documentation

Overview

golidator.go

Index

Constants

View Source
const CodeOneOf = combinator.CodeOneOf

Variables

This section is empty.

Functions

func AnyOf

func AnyOf[T any](schemaList ...combinator.Schema[T]) *combinator.AnyOfSchema[T]

func Array

func Array[E any]() *array.Schema[E]

func Boolean

func Boolean() *boolean.Schema

func Date

func Date() *date.Schema

func Duration

func Duration() *duration.Schema

func NumberSchemaOf

func NumberSchemaOf[N types.Number]() *number.Schema[N]

func Object

func Object[T any](builder func(target *T, schemaValue *object.Schema[T])) *object.Schema[T]

func OneOf

func OneOf[T any](schemaList ...combinator.Schema[T]) *combinator.OneOfSchema[T]

func Record

func Record[V any]() *record.Schema[V]

func Register

func Register(schemaValue AnySchema)

func ResetRegistry

func ResetRegistry()

func Text

func Text() *text.Schema

func Validate

func Validate[T any](input any, optionList ...Option) (T, error)

Types

type AnyOfSchema

type AnyOfSchema[T any] = combinator.AnyOfSchema[T]

type AnySchema

type AnySchema = schema.AnySchema

type ArraySchema

type ArraySchema[E any] = array.Schema[E]

type BooleanSchema

type BooleanSchema = boolean.Schema

type CombinatorSchema

type CombinatorSchema[T any] = combinator.Schema[T]

type DateSchema

type DateSchema = date.Schema

type DurationSchema

type DurationSchema = duration.Schema

type Formatter

type Formatter = schema.Formatter

type Issue

type Issue = issues.Issue

type Number

type Number = types.Number

type NumberSchema

type NumberSchema[N types.Number] = number.Schema[N]

type ObjectSchema

type ObjectSchema[T any] = object.Schema[T]

type OneOfSchema

type OneOfSchema[T any] = combinator.OneOfSchema[T]

type Option

type Option = schema.Option

func WithAdditionalDateLayouts

func WithAdditionalDateLayouts(layouts ...string) Option

func WithCoerce

func WithCoerce(value bool) Option

func WithCoerceDateUnixMilliseconds

func WithCoerceDateUnixMilliseconds(value bool) Option

func WithCoerceDateUnixSeconds

func WithCoerceDateUnixSeconds(value bool) Option

func WithCoerceDurationMilliseconds

func WithCoerceDurationMilliseconds(value bool) Option

func WithCoerceDurationSeconds

func WithCoerceDurationSeconds(value bool) Option

func WithCoerceNumberUnderscore

func WithCoerceNumberUnderscore(value bool) Option

func WithCoerceTrimSpace

func WithCoerceTrimSpace(value bool) Option

func WithDateLayouts

func WithDateLayouts(layouts ...string) Option

func WithDefaultOnNull

func WithDefaultOnNull(value bool) Option

func WithFailFast

func WithFailFast(value bool) Option

func WithFormatter

func WithFormatter(formatter Formatter) Option

func WithMaxIssues

func WithMaxIssues(value int) Option

func WithOmitZero

func WithOmitZero(value bool) Option

func WithTimeLocation

func WithTimeLocation(value *time.Location) Option

type Options

type Options = schema.Options

type RecordSchema

type RecordSchema[V any] = record.Schema[V]

type TextSchema

type TextSchema = text.Schema

type ValidationError

type ValidationError = issues.ValidationError

Directories

Path Synopsis
internal
ast
internal/ast/hash.go
internal/ast/hash.go
codec
internal/codec/decode.go
internal/codec/decode.go
defaults
internal/defaults/apply.go
internal/defaults/apply.go
engine
internal/engine/context.go
internal/engine/context.go
issues
internal/issues/format.go
internal/issues/format.go
path
internal/path/builder.go
internal/path/builder.go
reflection
internal/reflection/field_name.go
internal/reflection/field_name.go
registry
internal/registry/registry.go
internal/registry/registry.go
ruleset
internal/ruleset/rule.go
internal/ruleset/rule.go
testkit
internal/testkit/validation.go
internal/testkit/validation.go
schema/options.go
schema/options.go
array
schema/array/rules.go
schema/array/rules.go
array/rule
schema/array/rule/eq.go
schema/array/rule/eq.go
boolean
schema/boolean/parse.go
schema/boolean/parse.go
combinator
schema/combinator/anyof.go
schema/combinator/anyof.go
date
schema/date/parse.go
schema/date/parse.go
date/rule
schema/date/rule/eq.go
schema/date/rule/eq.go
duration
schema/duration/parse.go
schema/duration/parse.go
duration/rule
schema/duration/rule/eq.go
schema/duration/rule/eq.go
number
schema/number/parse.go
schema/number/parse.go
number/rule
schema/number/rule/eq.go
schema/number/rule/eq.go
number/util
schema/number/util/is_nan.go
schema/number/util/is_nan.go
object
schema/object/field.go
schema/object/field.go
object/rule
schema/object/rule/comparator_eqcsfield.go
schema/object/rule/comparator_eqcsfield.go
record
schema/record/rules.go
schema/record/rules.go
record/rule
schema/record/rule/eq.go
schema/record/rule/eq.go
text
schema/text/parser.go
schema/text/parser.go
text/rule
schema/text/rule/ascii.go
schema/text/rule/ascii.go

Jump to

Keyboard shortcuts

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