| // compile | |
| // Copyright 2025 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package main | |
| type Unsigned interface { | |
| ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | |
| } | |
| // a Validator instance | |
| type Validator []Validable | |
| type Numeric interface { | |
| ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~float32 | ~float64 | |
| } | |
| func (v Validator) Valid() bool { | |
| for _, field := range v { | |
| if !field.Validate() { | |
| return false | |
| } | |
| } | |
| return true | |
| } | |
| type Validable interface { | |
| Validate() bool | |
| } | |
| type FieldDef[T any] struct { | |
| value T | |
| rules []Rule[T] | |
| } | |
| func (f FieldDef[T]) Validate() bool { | |
| for _, rule := range f.rules { | |
| if !rule(f) { | |
| return false | |
| } | |
| } | |
| return true | |
| } | |
| type Rule[T any] = func(FieldDef[T]) bool | |
| func Field[T any](value T, rules ...Rule[T]) *FieldDef[T] { | |
| return &FieldDef[T]{value: value, rules: rules} | |
| } | |
| type StringRule = Rule[string] | |
| type NumericRule[T Numeric] = Rule[T] | |
| type UnsignedRule[T Unsigned] = Rule[T] | |
| func MinS(n int) StringRule { | |
| return func(fd FieldDef[string]) bool { | |
| return len(fd.value) < n | |
| } | |
| } | |
| func MinD[T Numeric](n T) NumericRule[T] { | |
| return func(fd FieldDef[T]) bool { | |
| return fd.value < n | |
| } | |
| } | |
| func MinU[T Unsigned](n T) UnsignedRule[T] { | |
| return func(fd FieldDef[T]) bool { | |
| return fd.value < n | |
| } | |
| } | |
| func main() { | |
| v := Validator{ | |
| Field("test", MinS(5)), | |
| } | |
| if !v.Valid() { | |
| println("invalid") | |
| return | |
| } | |
| println("valid") | |
| } |