Playground validator provider
Struct validator implementing bootstrap.StructValidator against go-playground/validator/v10. Piko's Money and Decimal validation rules ship pre-registered.
Overview
The provider wraps go-playground/validator/v10, the standard library for tag-driven struct validation in Go, and adds Piko-aware rules for the wdk/maths types without extra configuration. The provider enables validator.WithRequiredStructEnabled() by default. The validator then descends into a nested struct field marked required instead of skipping it, matching the go-playground semantics.
The package is pure Go. It carries no build tags and no CGO, so it runs the same way in interpreted dev mode and in compiled builds.
Validator.Struct(any) error satisfies the bootstrap.StructValidator interface, so wiring takes a single WithValidator line and no adapter glue. When you configure no validator on Piko, the framework skips struct validation entirely. It treats WithValidator as opt-in instead of required.
Pre-registered rules
NewValidator registers eight tags for the wdk/maths types before it applies any custom rule:
money_positive,money_negative,money_not_negative,money_not_zero. Sign and zero checks formaths.Moneyfields.decimal_positive,decimal_negative,decimal_not_negative,decimal_not_zero. The same checks formaths.Decimalfields.
Each rule is nil-pointer-safe and error-aware. The rules accept both a value field and a *maths.Money or *maths.Decimal pointer field. A nil pointer returns a fixed result for the rule and never panics. Any value carrying an internal error fails its rule.
Custom rules
You can extend the validator in three ways. WithRegistration(tag, fn) registers a single tag-to-function pairing. WithPlaygroundOption(...) accepts raw validator.Option values for cases where the playground library exposes something the wrapper does not, such as alias registration, custom type translation, or struct-level validators. Validator.Underlying() returns the underlying *validator.Validate for registration after construction.
NewValidator applies your WithRegistration tags last, after the built-in Money and Decimal rules. Reusing a built-in tag name overrides that rule.
Configuration
import (
"strings"
"github.com/go-playground/validator/v10"
playground "piko.sh/piko/wdk/validation/validation_provider_playground"
)
validator := playground.NewValidator(
playground.WithRegistration("uppercase", func(fl validator.FieldLevel) bool {
s := fl.Field().String()
return s == strings.ToUpper(s)
}),
)
NewValidator is functional-options-shaped, not Config-shaped. There is no TagName field, the wrapper applies the playground library's default (validate).
Bootstrap
ssr := piko.New(
piko.WithValidator(validator),
)
See also
Framework docs:
- Maths API reference, the Money and Decimal types whose validation rules ship pre-registered.
External:
- go-playground/validator, the underlying validator and the full tag reference.