valid

package module
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Feb 8, 2025 License: MIT Imports: 7 Imported by: 0

README

Valid 🛡️

Go Reference Go Report Card Coverage Status License

A lightweight, fluent validation library for Go with zero dependencies. Features type-safe validators and built-in internationalization support.

Features ✨

  • 🔄 Fluent chainable API
  • 🎯 Type-specific validations
  • 🌍 Built-in i18n support (EN/ES)
  • ⚡ Zero external dependencies
  • 🔍 Comprehensive error messages
  • 💪 Strong type safety
  • 🧪 100% test coverage

Installation 📦

go get -u github.com/techforge-lat/valid

Quick Start 🚀

package main

import (
    "fmt"
    "github.com/techforge-lat/valid"
)

type User struct {
    Age       int64
    Email     string
    Score     float64
    Tags      []string
}

func (u *User) Validate() error {
    v := valid.New()
    // Optional: set locale (default is ES)
    v.SetLocale(valid.LocaleEN)

    v.Int("age", u.Age, valid.NumberRules[int64]().
        Required().
        Between(18, 130).
        Build()...)

    v.String("email", u.Email, valid.StringRules().
        Required().
        Email().
        Build()...)

    v.Float64("score", u.Score, valid.FloatRules[float64]().
        Required().
        Between(0, 100).
        Precision(2).
        Build()...)

    v.StringSlice("tags", u.Tags).
        Required().
        MinLength(1).
        MaxLength(5)

    if v.HasErrors() {
        return v.Errors()
    }

    return nil
}

func main() {
    user := &User{
        Age:     15,
        Email:   "invalid@email",
        Score:   75.456,
        Tags:    []string{},
    }

    if err := user.Validate(); err != nil {
        fmt.Printf("Validation errors:\n%s\n", err)
    }
}

Internationalization 🌍

The library provides built-in support for English and Spanish:

// Create validator (defaults to Spanish)
v := valid.New()

// Set locale to English
v.SetLocale(valid.LocaleEN)

// Available locales
valid.LocaleES // Spanish
valid.LocaleEN // English

// Error messages will be in the selected language
v.String("name", "", valid.StringRules().Required().Build()...)
// EN: "field is required"
// ES: "el campo es requerido"

Available Validators 📝

String Validation
v.String("field", value, valid.StringRules().
    Required().
    MinLength(5).
    MaxLength(100).
    Email().
    Build()...)
Number Validation (Integer)
v.Int("field", value, valid.NumberRules[int64]().
    Required().
    Min(0).
    Max(100).
    Between(18, 65).
    Build()...)
Float Validation
v.Float64("field", value, valid.FloatRules[float64]().
    Required().
    Between(0, 100).
    Precision(2).
    Build()...)
Time Validation
v.Time("field", value, valid.TimeRules().
    Required().
    Past().
    After(startDate).
    Before(endDate).
    Between(start, end).
    MinAge(18).
    MaxAge(100).
    Build()...)
Slice Validation
// String slice
v.StringSlice("field", value).
    Required().
    MinLength(1).
    MaxLength(10)

// Number slice
v.Int64Slice("field", value).
    Required().
    MinLength(1).
    Min(0).
    Max(100)

// Float slice
v.Float64Slice("field", value).
    Required().
    MinLength(1).
    Min(0.0).
    Max(100.0)

Error Handling 🚨

ValidationErrors provides both individual error details and a formatted string:

if v.HasErrors() {
    errors := v.Errors()
    
    // Access individual errors
    for _, err := range errors {
        fmt.Printf("Field: %s, Message: %s\n", err.Field, err.Message)
    }
    
    // Get formatted error string
    fmt.Println(errors.Error())
    // EN: "age: must be greater than or equal to 18; email: invalid email format"
    // ES: "age: debe ser mayor o igual a 18; email: formato de correo electrónico inválido"
}

Contributing 🤝

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License 📄

This project is licensed under the MIT License - see the LICENSE file for details.

Support 💬

  • Create an issue for bug reports
  • Start a discussion for feature requests
  • Check out the documentation

Made with ❤️ by TechForge LATAM

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Float64Option added in v1.0.0

type Float64Option[T constraints.Float] func(*Float64Validator[T])

Option types for different validators

type Float64RuleBuilder added in v1.0.0

type Float64RuleBuilder[T constraints.Float] struct {
	// contains filtered or unexported fields
}

func FloatRules added in v1.0.0

func FloatRules[T constraints.Float]() *Float64RuleBuilder[T]

func (*Float64RuleBuilder[T]) Between added in v1.0.0

func (b *Float64RuleBuilder[T]) Between(min, max T) *Float64RuleBuilder[T]

Between validates value is between min and max

func (*Float64RuleBuilder[T]) Build added in v1.0.0

func (b *Float64RuleBuilder[T]) Build() []Float64Option[T]

func (*Float64RuleBuilder[T]) Max added in v1.0.0

func (b *Float64RuleBuilder[T]) Max(max T) *Float64RuleBuilder[T]

Max validates maximum value

func (*Float64RuleBuilder[T]) Min added in v1.0.0

func (b *Float64RuleBuilder[T]) Min(min T) *Float64RuleBuilder[T]

Min validates minimum value

func (*Float64RuleBuilder[T]) Precision added in v1.0.0

func (b *Float64RuleBuilder[T]) Precision(decimals int) *Float64RuleBuilder[T]

Precision validates decimal precision

func (*Float64RuleBuilder[T]) Required added in v1.0.0

func (b *Float64RuleBuilder[T]) Required() *Float64RuleBuilder[T]

Required validates that the float is not zero

type Float64SliceValidator added in v1.0.0

type Float64SliceValidator struct {
	*SliceValidator[float64]
}

Float64SliceValidator handles float64 slice validation

func NewFloat64SliceValidator added in v1.0.0

func NewFloat64SliceValidator(v *Validator, field string, value []float64) *Float64SliceValidator

func (*Float64SliceValidator) Between added in v1.0.0

func (sv *Float64SliceValidator) Between(min, max float64) *Float64SliceValidator

Between validates values are between min and max

func (*Float64SliceValidator) Max added in v1.0.0

Max validates maximum value for all elements

func (*Float64SliceValidator) Min added in v1.0.0

Min validates minimum value for all elements

type Float64Validator added in v1.0.0

type Float64Validator[T constraints.Float] struct {
	// contains filtered or unexported fields
}

Float64Validator handles floating-point validation

type Int64SliceValidator added in v1.0.0

type Int64SliceValidator struct {
	*SliceValidator[int64]
}

Int64SliceValidator handles int64 slice validation

func NewInt64SliceValidator added in v1.0.0

func NewInt64SliceValidator(v *Validator, field string, value []int64) *Int64SliceValidator

func (*Int64SliceValidator) Between added in v1.0.0

func (sv *Int64SliceValidator) Between(min, max int64) *Int64SliceValidator

Between validates values are between min and max

func (*Int64SliceValidator) Max added in v1.0.0

Max validates maximum value for all elements

func (*Int64SliceValidator) Min added in v1.0.0

Min validates minimum value for all elements

type Locale added in v1.0.0

type Locale string
const (
	LocaleES Locale = "es"
	LocaleEN Locale = "en"
)

type MessageKey added in v1.0.0

type MessageKey string
const (
	// Field validations
	MsgRequired       MessageKey = "required"
	MsgMinLength      MessageKey = "min_length"
	MsgMaxLength      MessageKey = "max_length"
	MsgEmail          MessageKey = "email"
	MsgMinValue       MessageKey = "min_value"
	MsgMaxValue       MessageKey = "max_value"
	MsgBetween        MessageKey = "between"
	MsgPrecision      MessageKey = "precision"
	MsgPast           MessageKey = "past"
	MsgFuture         MessageKey = "future"
	MsgAfter          MessageKey = "after"
	MsgBefore         MessageKey = "before"
	MsgBetweenDates   MessageKey = "between_dates"
	MsgWeekday        MessageKey = "weekday"
	MsgMaxAge         MessageKey = "max_age"
	MsgMinAge         MessageKey = "min_age"
	MsgSliceRequired  MessageKey = "slice_required"
	MsgSliceMinLength MessageKey = "slice_min_length"
	MsgSliceMaxLength MessageKey = "slice_max_length"
	MsgSliceLength    MessageKey = "slice_length"
	MsgSliceMin       MessageKey = "slice_min"
	MsgSliceMax       MessageKey = "slice_max"
	MsgSliceBetween   MessageKey = "slice_between"
	MsgInvalidUUID    MessageKey = "invalid_uuid"
	MsgOneOf          MessageKey = "one_of"
)

type MessageParams added in v1.0.0

type MessageParams map[string]interface{}

type NumberOption added in v1.0.0

type NumberOption[T constraints.Integer] func(*NumberValidator[T])

Option types for different validators

type NumberRuleBuilder added in v1.0.0

type NumberRuleBuilder[T constraints.Integer] struct {
	// contains filtered or unexported fields
}

func NumberRules added in v1.0.0

func NumberRules[T constraints.Integer]() *NumberRuleBuilder[T]

func (*NumberRuleBuilder[T]) Between added in v1.0.0

func (b *NumberRuleBuilder[T]) Between(min, max T) *NumberRuleBuilder[T]

Between validates value is between min and max

func (*NumberRuleBuilder[T]) Build added in v1.0.0

func (b *NumberRuleBuilder[T]) Build() []NumberOption[T]

func (*NumberRuleBuilder[T]) Max added in v1.0.0

func (b *NumberRuleBuilder[T]) Max(max T) *NumberRuleBuilder[T]

Max validates maximum value

func (*NumberRuleBuilder[T]) Min added in v1.0.0

func (b *NumberRuleBuilder[T]) Min(min T) *NumberRuleBuilder[T]

Min validates minimum value

func (*NumberRuleBuilder[T]) Required added in v1.0.0

func (b *NumberRuleBuilder[T]) Required() *NumberRuleBuilder[T]

Required validates that the number is not zero

type NumberValidator added in v1.0.0

type NumberValidator[T constraints.Integer] struct {
	// contains filtered or unexported fields
}

NumberValidator handles integer validation

type SliceValidator

type SliceValidator[T any] struct {
	// contains filtered or unexported fields
}

SliceValidator handles slice validation

func NewSliceValidator added in v1.0.0

func NewSliceValidator[T any](v *Validator, field string, value []T) *SliceValidator[T]

func (*SliceValidator[T]) Each added in v1.0.0

func (sv *SliceValidator[T]) Each(fn func(*Validator, int, T)) *SliceValidator[T]

Each applies a validation function to each element

func (*SliceValidator[T]) Length added in v1.0.0

func (sv *SliceValidator[T]) Length(length int) *SliceValidator[T]

Length validates exact slice length

func (*SliceValidator[T]) MaxLength

func (sv *SliceValidator[T]) MaxLength(max int) *SliceValidator[T]

MaxLength validates maximum slice length

func (*SliceValidator[T]) MinLength

func (sv *SliceValidator[T]) MinLength(min int) *SliceValidator[T]

MinLength validates minimum slice length

func (*SliceValidator[T]) Required

func (sv *SliceValidator[T]) Required() *SliceValidator[T]

Required validates that the slice is not empty

type StringOption added in v1.0.0

type StringOption func(*StringValidator)

Option types for different validators

type StringRuleBuilder added in v1.0.0

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

RuleBuilder types for fluent validation definition

func StringRules added in v1.0.0

func StringRules() *StringRuleBuilder

Constructor functions for rule builders

func (*StringRuleBuilder) Build added in v1.0.0

func (b *StringRuleBuilder) Build() []StringOption

Build methods return the accumulated validation rules

func (*StringRuleBuilder) Email added in v1.0.0

Email validates email format

func (*StringRuleBuilder) MaxLength added in v1.0.0

func (b *StringRuleBuilder) MaxLength(max int) *StringRuleBuilder

MaxLength validates maximum string length

func (*StringRuleBuilder) MinLength added in v1.0.0

func (b *StringRuleBuilder) MinLength(min int) *StringRuleBuilder

MinLength validates minimum string length

func (*StringRuleBuilder) OneOf added in v1.3.0

func (b *StringRuleBuilder) OneOf(values ...string) *StringRuleBuilder

Or validates that the string is not empty

func (*StringRuleBuilder) Required added in v1.0.0

func (b *StringRuleBuilder) Required() *StringRuleBuilder

Required validates that the string is not empty

func (*StringRuleBuilder) UUID added in v1.2.0

Required validates that the string is not empty

type StringValidator

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

StringValidator handles string validation

type TimeOption added in v1.0.0

type TimeOption func(*TimeValidator)

TimeOption defines a validation option for time

type TimeRuleBuilder added in v1.0.0

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

TimeRuleBuilder builds validation rules for time.Time

func TimeRules added in v1.0.0

func TimeRules() *TimeRuleBuilder

TimeRules starts a chain of time validation rules

func (*TimeRuleBuilder) After added in v1.0.0

After validates that the time is after the specified time

func (*TimeRuleBuilder) Before added in v1.0.0

func (b *TimeRuleBuilder) Before(t time.Time) *TimeRuleBuilder

Before validates that the time is before the specified time

func (*TimeRuleBuilder) Between added in v1.0.0

func (b *TimeRuleBuilder) Between(start, end time.Time) *TimeRuleBuilder

Between validates that the time is between two times

func (*TimeRuleBuilder) Build added in v1.0.0

func (b *TimeRuleBuilder) Build() []TimeOption

Build returns the accumulated rules

func (*TimeRuleBuilder) Future added in v1.0.0

func (b *TimeRuleBuilder) Future() *TimeRuleBuilder

Future validates that the time is in the future

func (*TimeRuleBuilder) MaxAge added in v1.0.0

func (b *TimeRuleBuilder) MaxAge(years int) *TimeRuleBuilder

MaxAge validates that the time represents an age not exceeding the specified years

func (*TimeRuleBuilder) MinAge added in v1.0.0

func (b *TimeRuleBuilder) MinAge(years int) *TimeRuleBuilder

MinAge validates that the time represents an age of at least the specified years

func (*TimeRuleBuilder) Past added in v1.0.0

func (b *TimeRuleBuilder) Past() *TimeRuleBuilder

Past validates that the time is in the past

func (*TimeRuleBuilder) Required added in v1.0.0

func (b *TimeRuleBuilder) Required() *TimeRuleBuilder

Required checks if the time is not zero

func (*TimeRuleBuilder) WeekDay added in v1.0.0

func (b *TimeRuleBuilder) WeekDay(days ...time.Weekday) *TimeRuleBuilder

WeekDay validates that the time is on specified weekdays

type TimeValidator added in v1.0.0

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

TimeValidator handles time validation

type Translator added in v1.0.0

type Translator interface {
	Translate(locale Locale, key MessageKey, params MessageParams) string
	SetLocale(locale Locale)
	GetLocale() Locale
}

func NewTranslator added in v1.0.0

func NewTranslator() Translator

type ValidationError

type ValidationError struct {
	Field      string     `json:"field"`
	Message    string     `json:"message"`
	MessageKey MessageKey `json:"message_key"`
}

ValidationError represents a single validation error

func (ValidationError) Error

func (e ValidationError) Error() string

type ValidationErrors

type ValidationErrors []ValidationError

ValidationErrors represents a collection of validation errors

func (ValidationErrors) Error

func (v ValidationErrors) Error() string

func (ValidationErrors) LogFields added in v1.0.0

func (v ValidationErrors) LogFields() []interface{}

LogFields method for logging

type Validator

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

Validator is the main validator instance

func New

func New() *Validator

New creates a new validator instance

func (*Validator) AddError

func (v *Validator) AddError(field string, key MessageKey, params MessageParams)

AddError adds a validation error

func (*Validator) Errors

func (v *Validator) Errors() ValidationErrors

func (*Validator) Float32 added in v1.0.0

func (v *Validator) Float32(field string, value float32, opts ...Float64Option[float32])

Float32 validates a floating-point field with the given options

func (*Validator) Float64 added in v1.0.0

func (v *Validator) Float64(field string, value float64, opts ...Float64Option[float64])

Float64 validates a floating-point field with the given options

func (*Validator) Float64Slice

func (v *Validator) Float64Slice(field string, value []float64) *Float64SliceValidator

Float64Slice creates a new slice validator for float64s

func (*Validator) HasErrors

func (v *Validator) HasErrors() bool

func (*Validator) Int

func (v *Validator) Int(field string, value int64, opts ...NumberOption[int64])

Int validates an integer field with the given options

func (*Validator) Int64Slice added in v1.0.0

func (v *Validator) Int64Slice(field string, value []int64) *Int64SliceValidator

Int64Slice creates a new slice validator for int64s

func (*Validator) SetLocale added in v1.0.0

func (v *Validator) SetLocale(locale Locale)

SetLocale sets the validator's locale

func (*Validator) String

func (v *Validator) String(field string, value string, opts ...StringOption)

String validates a string field with the given options

func (*Validator) StringSlice added in v1.0.0

func (v *Validator) StringSlice(field string, value []string) *SliceValidator[string]

StringSlice creates a new slice validator for strings

func (*Validator) Time added in v1.0.0

func (v *Validator) Time(field string, value time.Time, opts ...TimeOption)

func (*Validator) Uint

func (v *Validator) Uint(field string, value uint, opts ...NumberOption[uint])

Jump to

Keyboard shortcuts

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