From 6ff35c62696ff23cc1b0785a8cdcb31fb3f7a696 Mon Sep 17 00:00:00 2001 From: Jamess-Lucass Date: Wed, 31 Jan 2024 21:55:54 +0000 Subject: [PATCH] feat(*): Added refine method --- examples/main.go | 17 +++++++++++++++++ int.go | 24 +----------------------- object.go | 43 +++++++++++++++++++++++++++++++++++++++++++ schema.go | 39 +++++++++++++++++++++++++++++++++++++++ string.go | 22 ---------------------- 5 files changed, 100 insertions(+), 45 deletions(-) diff --git a/examples/main.go b/examples/main.go index 2a62f07..b5ddcfe 100644 --- a/examples/main.go +++ b/examples/main.go @@ -19,6 +19,7 @@ func main() { Age: 10, } + // 1 s1 := schema.Object(map[string]schema.ISchema{ "Firstname": schema.String().Min(5), "Lastname": schema.Int(), @@ -26,4 +27,20 @@ func main() { }).Parse(user) fmt.Printf("(1): is valid: %t\n", s1.IsValid()) + + // 2 + s2 := schema.String().Refine(func(value string) bool { + return value == "john" + }).Parse("john") + + fmt.Printf("(2): is valid: %t\n", s2.IsValid()) + + // 3 + s3 := schema.Object(map[string]schema.ISchema{ + "Firstname": schema.String(), + }).Refine(func(value map[string]interface{}) bool { + return value["Firstname"] == "john" + }).Parse(user) + + fmt.Printf("(3): is valid: %t\n", s3.IsValid()) } diff --git a/int.go b/int.go index 54e8dfb..0ac8838 100644 --- a/int.go +++ b/int.go @@ -40,26 +40,4 @@ func (s *IntSchema) Gt(min int) *IntSchema { s.validators = append(s.validators, validator) return s -} - -func (s *IntSchema) Parse(value any) *ValidationResult { - val, ok := value.(int) - if !ok { - return &ValidationResult{Errors: []ValidationError{{Path: "", Message: fmt.Sprintf("Expected int, received %T", value)}}} - } - - res := &ValidationResult{} - - for _, validator := range s.validators { - if !validator.ValidateFunc(val) { - err := ValidationError{ - Path: "", - Message: validator.MessageFunc(val), - } - - res.Errors = append(res.Errors, err) - } - } - - return res -} +} \ No newline at end of file diff --git a/object.go b/object.go index 110b604..38d82ba 100644 --- a/object.go +++ b/object.go @@ -7,6 +7,7 @@ import ( type ObjectSchema struct { value map[string]ISchema + Schema[map[string]interface{}] } var _ ISchema = (*ObjectSchema)(nil) @@ -15,6 +16,19 @@ func Object(obj map[string]ISchema) *ObjectSchema { return &ObjectSchema{value: obj} } +func (s *ObjectSchema) Refine(predicate func(map[string]interface{}) bool) *ObjectSchema { + validator := Validator[map[string]interface{}]{ + MessageFunc: func(value map[string]interface{}) string { + return "Invalid input" + }, + ValidateFunc: predicate, + } + + s.validators = append(s.validators, validator) + + return s +} + func (s *ObjectSchema) Parse(value any) *ValidationResult { t := reflect.TypeOf(value) val := reflect.ValueOf(value) @@ -51,5 +65,34 @@ func (s *ObjectSchema) Parse(value any) *ValidationResult { } } + valueMap := StructToMap(value) + + for _, validator := range s.validators { + if !validator.ValidateFunc(valueMap) { + err := ValidationError{ + Path: "", + Message: validator.MessageFunc(valueMap), + } + + res.Errors = append(res.Errors, err) + } + } + return res } + +func StructToMap(item interface{}) map[string]interface{} { + result := map[string]interface{}{} + + val := reflect.ValueOf(item) + typ := reflect.TypeOf(item) + + for i := 0; i < val.NumField(); i++ { + field := typ.Field(i) + value := val.Field(i).Interface() + + result[field.Name] = value + } + + return result +} diff --git a/schema.go b/schema.go index 196c838..0ea5e82 100644 --- a/schema.go +++ b/schema.go @@ -1,5 +1,9 @@ package schema +import ( + "fmt" +) + type ValidationResult struct { Errors []ValidationError } @@ -29,3 +33,38 @@ type Validator[T any] struct { MessageFunc func(T) string ValidateFunc func(T) bool } + +func (s *Schema[T]) Refine(predicate func(T) bool) *Schema[T] { + validator := Validator[T]{ + MessageFunc: func(value T) string { + return "Invalid input" + }, + ValidateFunc: predicate, + } + + s.validators = append(s.validators, validator) + + return s +} + +func (s *Schema[T]) Parse(value any) *ValidationResult { + val, ok := value.(T) + if !ok { + return &ValidationResult{Errors: []ValidationError{{Path: "", Message: fmt.Sprintf("Expected string, received %T", value)}}} + } + + res := &ValidationResult{} + + for _, validator := range s.validators { + if !validator.ValidateFunc(val) { + err := ValidationError{ + Path: "", + Message: validator.MessageFunc(val), + } + + res.Errors = append(res.Errors, err) + } + } + + return res +} diff --git a/string.go b/string.go index 0e662bd..8be49b2 100644 --- a/string.go +++ b/string.go @@ -121,25 +121,3 @@ func (s *StringSchema) EndsWith(str string) *StringSchema { return s } - -func (s *StringSchema) Parse(value any) *ValidationResult { - val, ok := value.(string) - if !ok { - return &ValidationResult{Errors: []ValidationError{{Path: "", Message: fmt.Sprintf("Expected string, received %T", value)}}} - } - - res := &ValidationResult{} - - for _, validator := range s.validators { - if !validator.ValidateFunc(val) { - err := ValidationError{ - Path: "", - Message: validator.MessageFunc(val), - } - - res.Errors = append(res.Errors, err) - } - } - - return res -}