Skip to content

Commit b37d688

Browse files
committed
Fix regexp support for type aliases
Fixes #90
1 parent c73a627 commit b37d688

File tree

3 files changed

+52
-17
lines changed

3 files changed

+52
-17
lines changed

Diff for: builtins.go

+13-14
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import (
2727
// as defined by the golang spec.
2828
func nonzero(v interface{}, param string) error {
2929
st := reflect.ValueOf(v)
30-
valid := true
30+
var valid bool
3131
switch st.Kind() {
3232
case reflect.String:
3333
valid = utf8.RuneCountInString(st.String()) != 0
@@ -62,7 +62,7 @@ func nonzero(v interface{}, param string) error {
6262
// for maps and slices it tests the number of items.
6363
func length(v interface{}, param string) error {
6464
st := reflect.ValueOf(v)
65-
valid := true
65+
var valid bool
6666
if st.Kind() == reflect.Ptr {
6767
if st.IsNil() {
6868
return nil
@@ -218,18 +218,17 @@ func max(v interface{}, param string) error {
218218
// regex is the builtin validation function that checks
219219
// whether the string variable matches a regular expression
220220
func regex(v interface{}, param string) error {
221-
s, ok := v.(string)
222-
if !ok {
223-
sptr, ok := v.(*string)
224-
if !ok {
225-
return ErrUnsupported
226-
}
227-
if sptr == nil {
221+
rv := reflect.ValueOf(v)
222+
if rv.Kind() == reflect.Ptr {
223+
if rv.IsNil() {
228224
return nil
229225
}
230-
s = *sptr
226+
rv = rv.Elem()
231227
}
232-
228+
if rv.Kind() != reflect.String {
229+
return ErrUnsupported
230+
}
231+
s := rv.String()
233232
re, err := regexp.Compile(param)
234233
if err != nil {
235234
return ErrBadParameter
@@ -241,7 +240,7 @@ func regex(v interface{}, param string) error {
241240
return nil
242241
}
243242

244-
// asInt retuns the parameter as a int64
243+
// asInt returns the parameter as a int64
245244
// or panics if it can't convert
246245
func asInt(param string) (int64, error) {
247246
i, err := strconv.ParseInt(param, 0, 64)
@@ -251,7 +250,7 @@ func asInt(param string) (int64, error) {
251250
return i, nil
252251
}
253252

254-
// asUint retuns the parameter as a uint64
253+
// asUint returns the parameter as a uint64
255254
// or panics if it can't convert
256255
func asUint(param string) (uint64, error) {
257256
i, err := strconv.ParseUint(param, 0, 64)
@@ -261,7 +260,7 @@ func asUint(param string) (uint64, error) {
261260
return i, nil
262261
}
263262

264-
// asFloat retuns the parameter as a float64
263+
// asFloat returns the parameter as a float64
265264
// or panics if it can't convert
266265
func asFloat(param string) (float64, error) {
267266
i, err := strconv.ParseFloat(param, 64)

Diff for: validator.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,11 @@ type ValidationFunc func(v interface{}, param string) error
114114

115115
// Validator implements a validator
116116
type Validator struct {
117-
// Tag name being used.
118-
tagName string
119117
// validationFuncs is a map of ValidationFuncs indexed
120118
// by their name.
121119
validationFuncs map[string]ValidationFunc
120+
// Tag name being used.
121+
tagName string
122122
// printJSON set to true will make errors print with the
123123
// name of their json field instead of their struct tag.
124124
// If no json tag is present the name of the struct field is used.

Diff for: validator_test.go

+37-1
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,9 @@ func (ms *MySuite) TestPrivateFields(c *C) {
576576
b string `validate:"min=1"`
577577
}
578578

579-
err := validator.Validate(test{})
579+
err := validator.Validate(test{
580+
b: "",
581+
})
580582
c.Assert(err, IsNil)
581583
}
582584

@@ -785,6 +787,40 @@ func (ms *MySuite) TestNonNilFunction(c *C) {
785787
c.Assert(err, IsNil)
786788
}
787789

790+
func (ms *MySuite) TestTypeAliases(c *C) {
791+
type A string
792+
type B int64
793+
type test struct {
794+
A1 A `validate:"regexp=^[0-9]+$"`
795+
A2 *A `validate:"regexp=^[0-9]+$"`
796+
B1 B `validate:"min=10"`
797+
B2 B `validate:"max=10"`
798+
}
799+
a123 := A("123")
800+
err := validator.Validate(test{
801+
A1: a123,
802+
A2: &a123,
803+
B1: B(11),
804+
B2: B(9),
805+
})
806+
c.Assert(err, IsNil)
807+
808+
abc := A("abc")
809+
err = validator.Validate(test{
810+
A1: abc,
811+
A2: &abc,
812+
B2: B(11),
813+
})
814+
c.Assert(err, NotNil)
815+
errs, ok := err.(validator.ErrorMap)
816+
c.Assert(ok, Equals, true)
817+
c.Assert(errs, HasLen, 4)
818+
c.Assert(errs["A1"], HasError, validator.ErrRegexp)
819+
c.Assert(errs["A2"], HasError, validator.ErrRegexp)
820+
c.Assert(errs["B1"], HasError, validator.ErrMin)
821+
c.Assert(errs["B2"], HasError, validator.ErrMax)
822+
}
823+
788824
type hasErrorChecker struct {
789825
*CheckerInfo
790826
}

0 commit comments

Comments
 (0)