diff --git a/examples/main.go b/examples/main.go index 63f0dd2..2b1c1e9 100644 --- a/examples/main.go +++ b/examples/main.go @@ -22,13 +22,13 @@ func main() { rules := validator.Rules( validator.RuleFor( user.Firstname, - validator.Required(), + validator.Required[string](), validator.Min(4), - Custom(), + Custom[string](), ).WithName("firstname"), validator.RuleFor( user.Lastname, - validator.Required(), + validator.Required[string](), validator.Min(3), ).WithName("lastname"), validator.RuleFor(user.Age, validator.Min(0)), @@ -45,7 +45,7 @@ func Custom[T any]() *validator.RuleConfig[T] { return fmt.Sprintf("'%s' must equal 'jane'", r.Value) }, ValidateFunc: func(r validator.RuleConfig[T]) bool { - val, ok := r.Value.(string) + val, ok := any(r.Value).(string) if !ok { return false } diff --git a/rules.go b/rules.go index 2335a3a..b2e2661 100644 --- a/rules.go +++ b/rules.go @@ -41,13 +41,16 @@ func Must[T any](predicate func() bool) *RuleConfig[T] { } } -func Required[T string]() *RuleConfig[T] { +func Required[T any]() *RuleConfig[T] { return &RuleConfig[T]{ MessageFunc: func(r RuleConfig[T]) string { return "Required" }, ValidateFunc: func(r RuleConfig[T]) bool { - return len(r.Value) > 0 + // if needed + // if val is string, check against nil, empty string + // if val is int, check against nil, 0 etc. + return any(r.Value) != nil }, } } diff --git a/test-01/main.go b/test-01/main.go index d960758..fa96519 100644 --- a/test-01/main.go +++ b/test-01/main.go @@ -7,14 +7,14 @@ type Validator struct { Errors []error } -type Rule func(*Validator) *Validator +type Rule[T any] func(*T) *T type StringValidator struct { - Validator + *Validator } -func NewStringValidator(value string, opts ...Rule) *StringValidator { - v := &StringValidator{Validator{value: value}} +func NewStringValidator(value string, opts ...StringRule) *StringValidator { + v := &StringValidator{&Validator{value: value}} for _, opt := range opts { opt(v) } @@ -22,8 +22,14 @@ func NewStringValidator(value string, opts ...Rule) *StringValidator { return v } -func NewIntValidator[T any](value T, opts ...Rule) *Validator { - v := &Validator{value: value} +type IntRule func(*IntValidator) *IntValidator + +type IntValidator struct { + *Validator +} + +func NewIntValidator(value int, opts ...IntRule) *IntValidator { + v := &IntValidator{&Validator{value: value}} for _, opt := range opts { opt(v) } @@ -31,17 +37,19 @@ func NewIntValidator[T any](value T, opts ...Rule) *Validator { return v } -func Min(min int) Rule { +func Min(min int) StringRule { return func(v *StringValidator) *StringValidator { - if len(v.value) < min { - v.Errors = append(v.Errors, fmt.Errorf("min length not met.")) + if str, ok := any(v.value).(string); ok { + if len(str) < min { + v.Errors = append(v.Errors, fmt.Errorf("min length not met.")) + } } return v } } -func Test() Rule { - return func(v *Validator) *Validator { +func Required[T any]() Rule[T] { + return func(v *T) *T { if str, ok := any(v.value).(string); ok { if str != "test" { v.Errors = append(v.Errors, fmt.Errorf("value does not equal 'test'")) @@ -52,7 +60,7 @@ func Test() Rule { } func main() { - v := NewStringValidator("john", Test(), Min(5)) + v := NewStringValidator("john", Required[StringValidator](), Min(5)) // NewValidator(10, Min(5), Test[string]()) fmt.Printf("error: %v\n", v.Errors) diff --git a/test-02/main.go b/test-02/main.go new file mode 100644 index 0000000..60a56b1 --- /dev/null +++ b/test-02/main.go @@ -0,0 +1,95 @@ +// zod + +package main + +import "fmt" + +type Schema struct{} + +func NewSchema() *Schema { + s := &Schema{} + + return s +} + +// string +type StringSchema struct { + checks []func(string) bool +} + +func (s *Schema) String() *StringSchema { + v := &StringSchema{} + + return v +} + +func (s *StringSchema) Min(min int) *StringSchema { + s.checks = append(s.checks, func(value string) bool { + if len(value) < min { + return false + } + return true + }) + + return s +} + +func (s *StringSchema) Parse(value any) bool { + val, ok := value.(string) + if !ok { + return false + } + + for _, check := range s.checks { + if !check(val) { + return false + } + } + + return true +} + +// int +type IntSchema struct { + checks []func(int) bool +} + +func (s *Schema) Int() *IntSchema { + v := &IntSchema{} + + return v +} + +func (s *IntSchema) LessThan(min int) *IntSchema { + s.checks = append(s.checks, func(value int) bool { + if value < min { + return true + } + return false + }) + + return s +} + +func (s *IntSchema) Parse(value any) bool { + val, ok := value.(int) + if !ok { + return false + } + + for _, check := range s.checks { + if !check(val) { + return false + } + } + + return true +} + +func main() { + v := NewSchema().String().Min(4).Parse("john") + s := NewSchema().Int().LessThan(4).Parse(1) + + fmt.Printf("(1) is valid: %t\n", v) + fmt.Printf("(2) is valid: %t\n", s) +} diff --git a/test/main.go b/test/main.go index 72b6428..e59c166 100644 --- a/test/main.go +++ b/test/main.go @@ -1,3 +1,4 @@ +// generics (simple) package main import "fmt" diff --git a/validator_test.go b/validator_test.go index 5b5d2c3..6e2d853 100644 --- a/validator_test.go +++ b/validator_test.go @@ -115,7 +115,7 @@ func Test_GreaterThanValid_ReturnsTrue(t *testing.T) { rule := validator.RuleFor( user.Age, - validator.Required(), + validator.Required[int](), validator.GreaterThan(17), )