Skip to content

Commit

Permalink
Merge pull request #642 from elias19r/issue-584-add-support-for-time-…
Browse files Browse the repository at this point in the history
…duration-type

Add support for time.Duration type
  • Loading branch information
deankarn committed Sep 27, 2020
2 parents 57b4fab + 1cbd308 commit 76981cc
Show file tree
Hide file tree
Showing 6 changed files with 1,321 additions and 78 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Expand Up @@ -6,6 +6,7 @@
# Folders
_obj
_test
bin

# Architecture specific extensions/prefixes
*.[568vq]
Expand All @@ -26,4 +27,4 @@ _testmain.go
*.out
*.txt
cover.html
README.html
README.html
17 changes: 7 additions & 10 deletions baked_in.go
Expand Up @@ -1145,7 +1145,7 @@ func isEq(fl FieldLevel) bool {
return int64(field.Len()) == p

case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p := asInt(param)
p := asIntFromType(field.Type(), param)

return field.Int() == p

Expand Down Expand Up @@ -1659,7 +1659,7 @@ func isGte(fl FieldLevel) bool {
return int64(field.Len()) >= p

case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p := asInt(param)
p := asIntFromType(field.Type(), param)

return field.Int() >= p

Expand Down Expand Up @@ -1706,7 +1706,7 @@ func isGt(fl FieldLevel) bool {
return int64(field.Len()) > p

case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p := asInt(param)
p := asIntFromType(field.Type(), param)

return field.Int() > p

Expand Down Expand Up @@ -1749,7 +1749,7 @@ func hasLengthOf(fl FieldLevel) bool {
return int64(field.Len()) == p

case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p := asInt(param)
p := asIntFromType(field.Type(), param)

return field.Int() == p

Expand Down Expand Up @@ -1885,7 +1885,7 @@ func isLte(fl FieldLevel) bool {
return int64(field.Len()) <= p

case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p := asInt(param)
p := asIntFromType(field.Type(), param)

return field.Int() <= p

Expand Down Expand Up @@ -1932,7 +1932,7 @@ func isLt(fl FieldLevel) bool {
return int64(field.Len()) < p

case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p := asInt(param)
p := asIntFromType(field.Type(), param)

return field.Int() < p

Expand Down Expand Up @@ -2205,11 +2205,8 @@ func isDatetime(fl FieldLevel) bool {

if field.Kind() == reflect.String {
_, err := time.Parse(param, field.String())
if err != nil {
return false
}

return true
return err == nil
}

panic(fmt.Sprintf("Bad field type %T", field.Interface()))
Expand Down
100 changes: 86 additions & 14 deletions doc.go
Expand Up @@ -355,42 +355,87 @@ equal to the parameter given. For strings, it checks that
the string length is exactly that number of characters. For slices,
arrays, and maps, validates the number of items.
Example #1
Usage: len=10
Example #2 (time.Duration)
For time.Duration, len will ensure that the value is equal to the duration given
in the parameter.
Usage: len=1h30m
Maximum
For numbers, max will ensure that the value is
less than or equal to the parameter given. For strings, it checks
that the string length is at most that number of characters. For
slices, arrays, and maps, validates the number of items.
Example #1
Usage: max=10
Example #2 (time.Duration)
For time.Duration, max will ensure that the value is less than or equal to the
duration given in the parameter.
Usage: max=1h30m
Minimum
For numbers, min will ensure that the value is
greater or equal to the parameter given. For strings, it checks that
the string length is at least that number of characters. For slices,
arrays, and maps, validates the number of items.
Example #1
Usage: min=10
Example #2 (time.Duration)
For time.Duration, min will ensure that the value is greater than or equal to
the duration given in the parameter.
Usage: min=1h30m
Equals
For strings & numbers, eq will ensure that the value is
equal to the parameter given. For slices, arrays, and maps,
validates the number of items.
Example #1
Usage: eq=10
Example #2 (time.Duration)
For time.Duration, eq will ensure that the value is equal to the duration given
in the parameter.
Usage: eq=1h30m
Not Equal
For strings & numbers, ne will ensure that the value is not
equal to the parameter given. For slices, arrays, and maps,
validates the number of items.
Example #1
Usage: ne=10
Example #2 (time.Duration)
For time.Duration, ne will ensure that the value is not equal to the duration
given in the parameter.
Usage: ne=1h30m
One Of
For strings, ints, and uints, oneof will ensure that the value
Expand Down Expand Up @@ -420,11 +465,17 @@ For time.Time ensures the time value is greater than time.Now.UTC().
Usage: gt
Example #3 (time.Duration)
For time.Duration, gt will ensure that the value is greater than the duration
given in the parameter.
Usage: gt=1h30m
Greater Than or Equal
Same as 'min' above. Kept both to make terminology with 'len' easier.
Example #1
Usage: gte=10
Expand All @@ -435,6 +486,13 @@ For time.Time ensures the time value is greater than or equal to time.Now.UTC().
Usage: gte
Example #3 (time.Duration)
For time.Duration, gte will ensure that the value is greater than or equal to
the duration given in the parameter.
Usage: gte=1h30m
Less Than
For numbers, this will ensure that the value is less than the parameter given.
Expand All @@ -446,10 +504,18 @@ Example #1
Usage: lt=10
Example #2 (time.Time)
For time.Time ensures the time value is less than time.Now.UTC().
Usage: lt
Example #3 (time.Duration)
For time.Duration, lt will ensure that the value is less than the duration given
in the parameter.
Usage: lt=1h30m
Less Than or Equal
Same as 'max' above. Kept both to make terminology with 'len' easier.
Expand All @@ -464,6 +530,13 @@ For time.Time ensures the time value is less than or equal to time.Now.UTC().
Usage: lte
Example #3 (time.Duration)
For time.Duration, lte will ensure that the value is less than or equal to the
duration given in the parameter.
Usage: lte=1h30m
Field Equals Another Field
This will validate the field value against another fields value either within
Expand Down Expand Up @@ -510,9 +583,9 @@ relative to the top level struct.
Field Greater Than Another Field
Only valid for Numbers and time.Time types, this will validate the field value
against another fields value either within a struct or passed in field.
usage examples are for validation of a Start and End date:
Only valid for Numbers, time.Duration and time.Time types, this will validate
the field value against another fields value either within a struct or passed in
field. usage examples are for validation of a Start and End date:
Example #1:
Expand All @@ -524,7 +597,6 @@ Example #2:
// Validating by field:
validate.VarWithValue(start, end, "gtfield")
Field Greater Than Another Relative Field
This does the same as gtfield except that it validates the field provided
Expand All @@ -534,9 +606,9 @@ relative to the top level struct.
Field Greater Than or Equal To Another Field
Only valid for Numbers and time.Time types, this will validate the field value
against another fields value either within a struct or passed in field.
usage examples are for validation of a Start and End date:
Only valid for Numbers, time.Duration and time.Time types, this will validate
the field value against another fields value either within a struct or passed in
field. usage examples are for validation of a Start and End date:
Example #1:
Expand All @@ -557,9 +629,9 @@ to the top level struct.
Less Than Another Field
Only valid for Numbers and time.Time types, this will validate the field value
against another fields value either within a struct or passed in field.
usage examples are for validation of a Start and End date:
Only valid for Numbers, time.Duration and time.Time types, this will validate
the field value against another fields value either within a struct or passed in
field. usage examples are for validation of a Start and End date:
Example #1:
Expand All @@ -580,9 +652,9 @@ to the top level struct.
Less Than or Equal To Another Field
Only valid for Numbers and time.Time types, this will validate the field value
against another fields value either within a struct or passed in field.
usage examples are for validation of a Start and End date:
Only valid for Numbers, time.Duration and time.Time types, this will validate
the field value against another fields value either within a struct or passed in
field. usage examples are for validation of a Start and End date:
Example #1:
Expand Down
21 changes: 21 additions & 0 deletions util.go
Expand Up @@ -4,6 +4,7 @@ import (
"reflect"
"strconv"
"strings"
"time"
)

// extractTypeInternal gets the actual underlying type of field value.
Expand Down Expand Up @@ -229,6 +230,26 @@ func asInt(param string) int64 {
return i
}

// asIntFromTimeDuration parses param as time.Duration and returns it as int64
// or panics on error.
func asIntFromTimeDuration(param string) int64 {
d, err := time.ParseDuration(param)
panicIf(err)

return int64(d)
}

// asIntFromType calls the proper function to parse param as int64,
// given a field's Type t.
func asIntFromType(t reflect.Type, param string) int64 {
switch t {
case timeDurationType:
return asIntFromTimeDuration(param)
default:
return asInt(param)
}
}

// asUint returns the parameter as a uint64
// or panics if it can't convert
func asUint(param string) uint64 {
Expand Down
4 changes: 3 additions & 1 deletion validator_instance.go
Expand Up @@ -43,7 +43,9 @@ const (
)

var (
timeType = reflect.TypeOf(time.Time{})
timeDurationType = reflect.TypeOf(time.Duration(0))
timeType = reflect.TypeOf(time.Time{})

defaultCField = &cField{namesEqual: true}
)

Expand Down

0 comments on commit 76981cc

Please sign in to comment.