Valgo Migration Notes
Valgo is pre-v1.0, so breaking changes can happen.
v0.9.0 - Stateless predicates and generalized numeric constructors
Section titled “v0.9.0 - Stateless predicates and generalized numeric constructors”Generalized numeric constructors
Valgo originally introduced a separate constructor for each numeric width when
Go did not support generics. At the time, constructors such as Int8(),
Int16(), Float32(), and Float64() were a practical way to provide a
type-safe API for each built-in numeric type.
Go has supported generics since Go 1.18, and Valgo’s numeric validator types
have been generic over an entire numeric family since v0.7. The specialized
constructors were retained for compatibility, but they no longer overcome a
language limitation on the Go versions Valgo supports. For example,
ValidatorInt[T] already supports every signed integer type, so requiring
Int16() instead of Int() for an int16 value adds another API name without
providing different rules or stronger type safety.
In v0.9.0, each primary constructor now uses the same constraint as its validator family:
Int()andIntP()acceptint,int8,int16,int32, andint64.Uint()andUintP()acceptuint,uint8,uint16,uint32, anduint64.Float()andFloatP()acceptfloat32andfloat64.
Callers can therefore choose a constructor by the validation behavior they need—signed integer, unsigned integer, or floating point—instead of by storage width.
Go infers and preserves the exact input type, including user-defined types, so the broader constructors do not weaken type safety:
type Attempts int8
attempts := Attempts(3)limit := uint32(100)ratio := float32(0.75)
v.Int(attempts).Between(0, 5)v.Uint(limit).GreaterThan(0)v.Float(ratio).Between(0, 1)The specialized constructors now only repeat the underlying storage width; they no longer provide the value they did before generics. Keeping every width-specific name as a first-class API would make the package, documentation, and future extensions larger without providing additional type safety, validation behavior, or rules. They are therefore deprecated compatibility aliases:
Int8,Int16,Int32,Int64and theirPformsUint8,Uint16,Uint32,Uint64and theirPformsFloat32,Float64and theirPforms
Existing code continues to work, but new code should use the primary family constructors. Migration changes only the constructor name; the inferred value type and validator rules stay the same:
v.Int16(value) // Deprecatedv.Int(value) // Preferred
v.Float64P(&rate) // Deprecatedv.FloatP(&rate) // PreferredRune/RuneP and Byte/ByteP remain supported because those names express
domain meaning, not merely storage width: a rune is a Unicode code point and a
byte is a unit of binary data.
Built-in rule logic functions
Valgo now exposes its built-in rule logic as ordinary boolean functions in
github.com/cohesivestack/valgo/is. These predicates do not create validation
contexts or localized errors. Existing validator methods keep their behavior
and now use the same predicates internally. See Stateless
Predicates for the API and examples.
v0.8.1 - Shorter string length validator names
Section titled “v0.8.1 - Shorter string length validator names”String length validators now have shorter preferred names:
ByteLengthreplacesOfByteLengthByteLengthBetweenreplacesOfByteLengthBetweenLengthreplacesOfLengthLengthBetweenreplacesOfLengthBetween
The Of* methods remain available as deprecated aliases in v0.8.1 for
compatibility. They will be removed in v1.0.
v0.8.0 - Go version and validation flow
Section titled “v0.8.0 - Go version and validation flow”- Valgo v0.8 is tested with Go 1.23 and later. Using one of these versions is recommended.
- When all
Or()alternatives fail, v0.8 produces one localized message that joins the alternatives. OR grouping and precedence remain consistent with v0.7. OrElse()adds a short-circuiting alternative that skips the rest of the validator chain when its left side succeeds.PathValid(),AllValid(), andAnyValid()query recorded validation results.IsValid()remains available but is deprecated in favor ofPathValid().- The
If*ValidandWhen*Validmethods conditionally merge validations or execute callbacks based on those recorded results. - Custom validators can supply missing message entries through
ValidatorContext.WithLocaleFallback().
v0.7.0 - Numeric validators switched to generics
Section titled “v0.7.0 - Numeric validators switched to generics”Numeric validators are now generic per family:
ValidatorInt[T ~int | ~int8 | ~int16 | ~int32 | ~int64]ValidatorUint[T ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64]ValidatorFloat[T ~float32 | ~float64]
Most call sites remain the same (constructors like v.Int16(...) still exist). You mainly need to update declared types.
v0.6.0 - String length counts runes (characters)
Section titled “v0.6.0 - String length counts runes (characters)”String length validators now measure runes instead of bytes:
- A multi-byte UTF-8 character counts as 1.
- Use explicit byte-length validators if you need
len(s)semantics.
Byte-based validators:
MaxBytesMinBytesOfByteLengthOfByteLengthBetween