Skip to content

Commit

Permalink
remove typedvalidator to firm package
Browse files Browse the repository at this point in the history
  • Loading branch information
s12chung committed Oct 9, 2023
1 parent db923f6 commit a5dda6e
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 74 deletions.
Original file line number Diff line number Diff line change
@@ -1,77 +1,74 @@
// Package typedvalidator contained typed validators with generics
package typedvalidator
package firm

import (
"reflect"

"github.com/s12chung/text2anki/pkg/firm"
)

// ValidatorX is a generic firm.Validator that has a typed ValidateTyped() function
type ValidatorX[T any] interface {
firm.Validator
ValidateX(data T) firm.ErrorMap
Validator
ValidateX(data T) ErrorMap
}

// MustNewStructX returns a new StructX, panics if there is an error
func MustNewStructX[T any](data T, ruleMap firm.RuleMap) StructX[T] {
func MustNewStructX[T any](data T, ruleMap RuleMap) StructX[T] {
return mustNewValidatorX(func() (StructX[T], error) { return NewStructX(data, ruleMap) })
}

// NewStructX returns a new StructX
func NewStructX[T any](data T, ruleMap firm.RuleMap) (StructX[T], error) {
validator, err := firm.NewStruct(data, ruleMap)
func NewStructX[T any](data T, ruleMap RuleMap) (StructX[T], error) {
validator, err := NewStruct(data, ruleMap)
if err != nil {
return StructX[T]{}, err
}
return StructX[T]{Struct: validator}, nil
}

// StructX is a Struct that's typed
type StructX[T any] struct{ firm.Struct }
type StructX[T any] struct{ Struct }

// ValidateX is firm.Validator.Validate(), but with a typed arg, so no type checking is done on runtime
func (s StructX[T]) ValidateX(data T) firm.ErrorMap { return validateX(s, data) }
func (s StructX[T]) ValidateX(data T) ErrorMap { return validateX(s, data) }

// MustNewSliceX returns a new SliceX, panics if there is an error
func MustNewSliceX[T any](data T, elementRules ...firm.Rule) SliceX[T] {
func MustNewSliceX[T any](data T, elementRules ...Rule) SliceX[T] {
return mustNewValidatorX(func() (SliceX[T], error) { return NewSliceX[T](data, elementRules...) })
}

// NewSliceX returns a new SliceX
func NewSliceX[T any](data T, elementRules ...firm.Rule) (SliceX[T], error) {
validator, err := firm.NewSlice(data, elementRules...)
func NewSliceX[T any](data T, elementRules ...Rule) (SliceX[T], error) {
validator, err := NewSlice(data, elementRules...)
if err != nil {
return SliceX[T]{}, err
}
return SliceX[T]{Slice: validator}, nil
}

// SliceX is a Slice that's typed
type SliceX[T any] struct{ firm.Slice }
type SliceX[T any] struct{ Slice }

// ValidateX is firm.Validator.Validate(), but with a typed arg, so no type checking is done on runtime
func (s SliceX[T]) ValidateX(data T) firm.ErrorMap { return validateX(s, data) }
func (s SliceX[T]) ValidateX(data T) ErrorMap { return validateX(s, data) }

// MustNewValueX returns a new ValueX, panics if there is an error
func MustNewValueX[T any](data T, rules ...firm.Rule) ValueX[T] {
func MustNewValueX[T any](data T, rules ...Rule) ValueX[T] {
return mustNewValidatorX(func() (ValueX[T], error) { return NewValueX[T](data, rules...) })
}

// NewValueX returns a new ValueX
func NewValueX[T any](data T, rules ...firm.Rule) (ValueX[T], error) {
validator, err := firm.NewValue(data, rules...)
func NewValueX[T any](data T, rules ...Rule) (ValueX[T], error) {
validator, err := NewValue(data, rules...)
if err != nil {
return ValueX[T]{}, err
}
return ValueX[T]{Value: validator}, nil
}

// ValueX is a Value that's typed
type ValueX[T any] struct{ firm.Value }
type ValueX[T any] struct{ Value }

// ValidateX is firm.Validator.Validate(), but with a typed arg, so no type checking is done on runtime
func (v ValueX[T]) ValidateX(data T) firm.ErrorMap { return validateX(v, data) }
func (v ValueX[T]) ValidateX(data T) ErrorMap { return validateX(v, data) }

func mustNewValidatorX[T any](f func() (T, error)) T {
validator, err := f()
Expand All @@ -81,9 +78,9 @@ func mustNewValidatorX[T any](f func() (T, error)) T {
return validator
}

func validateX(validator firm.Validator, data any) firm.ErrorMap {
func validateX(validator Validator, data any) ErrorMap {
value := reflect.ValueOf(data)
errorMap := firm.ErrorMap{}
validator.ValidateMerge(value, firm.TypeName(value), errorMap)
errorMap := ErrorMap{}
validator.ValidateMerge(value, TypeName(value), errorMap)
return errorMap.Finish()
}
Original file line number Diff line number Diff line change
@@ -1,41 +1,13 @@
package typedvalidator
package firm

import (
"fmt"
"reflect"
"testing"

"github.com/stretchr/testify/require"

"github.com/s12chung/text2anki/pkg/firm"
)

type presentRule struct{}

const presentRuleKey = "presentRule"

func (p presentRule) ValidateValue(value reflect.Value) firm.ErrorMap {
if value.IsZero() {
return firm.ErrorMap{presentRuleKey: *presentRuleError("")}
}
return nil
}
func (p presentRule) ValidateType(_ reflect.Type) *firm.RuleTypeError { return nil }

func presentRuleError(errorKey firm.ErrorKey) *firm.TemplateError {
return &firm.TemplateError{ErrorKey: errorKey, Template: "test"}
}

type onlyKindRule struct{ kind reflect.Kind }

func (o onlyKindRule) ValidateValue(_ reflect.Value) firm.ErrorMap { return nil }
func (o onlyKindRule) ValidateType(typ reflect.Type) *firm.RuleTypeError {
if typ.Kind() != o.kind {
return firm.NewRuleTypeError(typ, "is not "+o.kind.String())
}
return nil
}

type testStruct struct {
WillV string
NoV string
Expand All @@ -44,12 +16,12 @@ type testStruct struct {
func TestNewStructX(t *testing.T) {
tcs := []struct {
name string
ruleMap firm.RuleMap
ruleMap RuleMap
err error
}{
{name: "normal", ruleMap: firm.RuleMap{"WillV": []firm.Rule{presentRule{}}}},
{name: "bad_rule", ruleMap: firm.RuleMap{"NotAField": []firm.Rule{presentRule{}}},
err: fmt.Errorf("field, NotAField, not found in type: typedvalidator.testStruct")},
{name: "normal", ruleMap: RuleMap{"WillV": []Rule{presentRule{}}}},
{name: "bad_rule", ruleMap: RuleMap{"NotAField": []Rule{presentRule{}}},
err: fmt.Errorf("field, NotAField, not found in type: firm.testStruct")},
}
for _, tc := range tcs {
tc := tc
Expand All @@ -63,7 +35,7 @@ func TestNewStructX(t *testing.T) {
}

require.NoError(err)
expected, err := firm.NewStruct(testStruct{}, tc.ruleMap)
expected, err := NewStruct(testStruct{}, tc.ruleMap)
require.NoError(err)

require.Equal(expected, validator.Struct)
Expand All @@ -72,14 +44,14 @@ func TestNewStructX(t *testing.T) {
}

func TestStructX_ValidateTyped(t *testing.T) {
errorKey := firm.ErrorKey("typedvalidator.testStruct.WillV." + presentRuleKey)
errorKey := ErrorKey("firm.testStruct.WillV." + presentRuleKey)

tcs := []validateTypedTC[testStruct]{
{name: "valid", data: testStruct{WillV: "ok"}},
{name: "invalid", data: testStruct{NoV: "not_ok"}, result: firm.ErrorMap{errorKey: *presentRuleError(errorKey)}},
{name: "invalid", data: testStruct{NoV: "not_ok"}, result: ErrorMap{errorKey: *presentRuleError(errorKey)}},
}
testValidateTyped(t, tcs, func() (ValidatorX[testStruct], error) {
return NewStructX(testStruct{}, firm.RuleMap{"WillV": []firm.Rule{presentRule{}}})
return NewStructX(testStruct{}, RuleMap{"WillV": []Rule{presentRule{}}})
})
}

Expand All @@ -88,11 +60,11 @@ func TestNewSliceX(t *testing.T) {

tcs := []struct {
name string
elementRules []firm.Rule
elementRules []Rule
err error
}{
{name: "normal", elementRules: []firm.Rule{presentRule{}}},
{name: "bad_rule", elementRules: []firm.Rule{intKindRule},
{name: "normal", elementRules: []Rule{presentRule{}}},
{name: "bad_rule", elementRules: []Rule{intKindRule},
err: fmt.Errorf("element type: %w", intKindRule.ValidateType(reflect.TypeOf(testStruct{})))},
}
for _, tc := range tcs {
Expand All @@ -107,7 +79,7 @@ func TestNewSliceX(t *testing.T) {
}

require.NoError(err)
expected, err := firm.NewSlice([]testStruct{}, tc.elementRules...)
expected, err := NewSlice([]testStruct{}, tc.elementRules...)
require.NoError(err)

require.Equal(expected, validator.Slice)
Expand All @@ -116,11 +88,11 @@ func TestNewSliceX(t *testing.T) {
}

func TestSliceX_ValidateTyped(t *testing.T) {
errorKey := firm.ErrorKey("[]typedvalidator.testStruct.[0]." + presentRuleKey)
errorKey := ErrorKey("[]firm.testStruct.[0]." + presentRuleKey)
tcs := []validateTypedTC[[]testStruct]{
{name: "valid", data: []testStruct{{WillV: "ok"}}},
{name: "invalid", data: []testStruct{{}},
result: firm.ErrorMap{errorKey: *presentRuleError(errorKey)}},
result: ErrorMap{errorKey: *presentRuleError(errorKey)}},
}
testValidateTyped(t, tcs, func() (ValidatorX[[]testStruct], error) {
return NewSliceX([]testStruct{}, presentRule{})
Expand All @@ -132,11 +104,11 @@ func TestNewValueX(t *testing.T) {

tcs := []struct {
name string
rules []firm.Rule
rules []Rule
err error
}{
{name: "normal", rules: []firm.Rule{presentRule{}}},
{name: "bad_rule", rules: []firm.Rule{intKindRule}, err: intKindRule.ValidateType(reflect.TypeOf(testStruct{}))},
{name: "normal", rules: []Rule{presentRule{}}},
{name: "bad_rule", rules: []Rule{intKindRule}, err: intKindRule.ValidateType(reflect.TypeOf(testStruct{}))},
}
for _, tc := range tcs {
tc := tc
Expand All @@ -150,7 +122,7 @@ func TestNewValueX(t *testing.T) {
}

require.NoError(err)
expected, err := firm.NewValue(testStruct{}, tc.rules...)
expected, err := NewValue(testStruct{}, tc.rules...)
require.NoError(err)

require.Equal(expected, validator.Value)
Expand All @@ -159,10 +131,10 @@ func TestNewValueX(t *testing.T) {
}

func TestValueX_ValidateTyped(t *testing.T) {
errorKey := firm.ErrorKey("typedvalidator.testStruct." + presentRuleKey)
errorKey := ErrorKey("firm.testStruct." + presentRuleKey)
tcs := []validateTypedTC[testStruct]{
{name: "valid", data: testStruct{WillV: "ok"}},
{name: "invalid", data: testStruct{}, result: firm.ErrorMap{errorKey: *presentRuleError(errorKey)}},
{name: "invalid", data: testStruct{}, result: ErrorMap{errorKey: *presentRuleError(errorKey)}},
}
testValidateTyped(t, tcs, func() (ValidatorX[testStruct], error) {
return NewValueX(testStruct{}, presentRule{})
Expand All @@ -172,7 +144,7 @@ func TestValueX_ValidateTyped(t *testing.T) {
type validateTypedTC[T any] struct {
name string
data T
result firm.ErrorMap
result ErrorMap
}

func testValidateTyped[T any](t *testing.T, tcs []validateTypedTC[T], newValidator func() (ValidatorX[T], error)) {
Expand Down

0 comments on commit a5dda6e

Please sign in to comment.