Files
appcore/validate/validate.go
2025-10-03 00:12:00 +05:30

77 lines
1.7 KiB
Go

// Copyright 2024 Patial Tech (Ankit Patial).
//
// This file is part of code.patial.tech/go/appcore, which is MIT licensed.
// See http://opensource.org/licenses/MIT
package validate
import (
"errors"
"fmt"
"reflect"
"strings"
"github.com/go-playground/validator/v10"
)
var validate *validator.Validate
func init() {
validate = validator.New()
// register function to get tag name from json tags.
validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
if name == "-" {
return ""
}
return name
})
}
// RegisterAlias for single/multuple tags
func RegisterAlias(alias, tags string) {
validate.RegisterAlias(alias, tags)
}
func RegisterValidation(tagName string, fn validator.Func, callValidationEvenIfNull ...bool) {
validate.RegisterValidation(tagName, fn, callValidationEvenIfNull...)
}
// Struct validator
func Struct(s any) error {
err := validate.Struct(s)
if IsInvalidValidationError(err) {
return err
}
var valErrs validator.ValidationErrors
if !errors.As(err, &valErrs) {
return err
}
var sb strings.Builder
for _, err := range valErrs {
switch err.Tag() {
case "required":
sb.WriteString(fmt.Sprintf("%s: is required.\n", err.Field()))
case "email":
sb.WriteString(fmt.Sprintf("%s: is invalid.\n", err.Field()))
default:
sb.WriteString(fmt.Sprintf("%s: %q validation failed.\n", err.Field(), err.Tag()))
}
}
return errors.New(sb.String())
}
// Map validator
func Map(data map[string]any, rules map[string]any) map[string]any {
return validate.ValidateMap(data, rules)
}
func IsInvalidValidationError(err error) bool {
var v *validator.InvalidValidationError
return errors.As(err, &v)
}