Merge pull request #642 from elias19r/issue-584-add-support-for-time-duration-type

Add support for time.Duration type
pull/671/head
Dean Karn 4 years ago committed by GitHub
commit 76981ccf75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      .gitignore
  2. 17
      baked_in.go
  3. 100
      doc.go
  4. 21
      util.go
  5. 4
      validator_instance.go
  6. 1254
      validator_test.go

3
.gitignore vendored

@ -6,6 +6,7 @@
# Folders # Folders
_obj _obj
_test _test
bin
# Architecture specific extensions/prefixes # Architecture specific extensions/prefixes
*.[568vq] *.[568vq]
@ -26,4 +27,4 @@ _testmain.go
*.out *.out
*.txt *.txt
cover.html cover.html
README.html README.html

@ -1145,7 +1145,7 @@ func isEq(fl FieldLevel) bool {
return int64(field.Len()) == p return int64(field.Len()) == p
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p := asInt(param) p := asIntFromType(field.Type(), param)
return field.Int() == p return field.Int() == p
@ -1659,7 +1659,7 @@ func isGte(fl FieldLevel) bool {
return int64(field.Len()) >= p return int64(field.Len()) >= p
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p := asInt(param) p := asIntFromType(field.Type(), param)
return field.Int() >= p return field.Int() >= p
@ -1706,7 +1706,7 @@ func isGt(fl FieldLevel) bool {
return int64(field.Len()) > p return int64(field.Len()) > p
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p := asInt(param) p := asIntFromType(field.Type(), param)
return field.Int() > p return field.Int() > p
@ -1749,7 +1749,7 @@ func hasLengthOf(fl FieldLevel) bool {
return int64(field.Len()) == p return int64(field.Len()) == p
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p := asInt(param) p := asIntFromType(field.Type(), param)
return field.Int() == p return field.Int() == p
@ -1885,7 +1885,7 @@ func isLte(fl FieldLevel) bool {
return int64(field.Len()) <= p return int64(field.Len()) <= p
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p := asInt(param) p := asIntFromType(field.Type(), param)
return field.Int() <= p return field.Int() <= p
@ -1932,7 +1932,7 @@ func isLt(fl FieldLevel) bool {
return int64(field.Len()) < p return int64(field.Len()) < p
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p := asInt(param) p := asIntFromType(field.Type(), param)
return field.Int() < p return field.Int() < p
@ -2205,11 +2205,8 @@ func isDatetime(fl FieldLevel) bool {
if field.Kind() == reflect.String { if field.Kind() == reflect.String {
_, err := time.Parse(param, field.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())) panic(fmt.Sprintf("Bad field type %T", field.Interface()))

100
doc.go

@ -355,8 +355,17 @@ equal to the parameter given. For strings, it checks that
the string length is exactly that number of characters. For slices, the string length is exactly that number of characters. For slices,
arrays, and maps, validates the number of items. arrays, and maps, validates the number of items.
Example #1
Usage: len=10 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 Maximum
For numbers, max will ensure that the value is For numbers, max will ensure that the value is
@ -364,8 +373,17 @@ less than or equal to the parameter given. For strings, it checks
that the string length is at most that number of characters. For that the string length is at most that number of characters. For
slices, arrays, and maps, validates the number of items. slices, arrays, and maps, validates the number of items.
Example #1
Usage: max=10 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 Minimum
For numbers, min will ensure that the value is For numbers, min will ensure that the value is
@ -373,24 +391,51 @@ greater or equal to the parameter given. For strings, it checks that
the string length is at least that number of characters. For slices, the string length is at least that number of characters. For slices,
arrays, and maps, validates the number of items. arrays, and maps, validates the number of items.
Example #1
Usage: min=10 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 Equals
For strings & numbers, eq will ensure that the value is For strings & numbers, eq will ensure that the value is
equal to the parameter given. For slices, arrays, and maps, equal to the parameter given. For slices, arrays, and maps,
validates the number of items. validates the number of items.
Example #1
Usage: eq=10 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 Not Equal
For strings & numbers, ne will ensure that the value is not For strings & numbers, ne will ensure that the value is not
equal to the parameter given. For slices, arrays, and maps, equal to the parameter given. For slices, arrays, and maps,
validates the number of items. validates the number of items.
Example #1
Usage: ne=10 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 One Of
For strings, ints, and uints, oneof will ensure that the value For strings, ints, and uints, oneof will ensure that the value
@ -420,11 +465,17 @@ For time.Time ensures the time value is greater than time.Now.UTC().
Usage: gt 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 Greater Than or Equal
Same as 'min' above. Kept both to make terminology with 'len' easier. Same as 'min' above. Kept both to make terminology with 'len' easier.
Example #1 Example #1
Usage: gte=10 Usage: gte=10
@ -435,6 +486,13 @@ For time.Time ensures the time value is greater than or equal to time.Now.UTC().
Usage: gte 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 Less Than
For numbers, this will ensure that the value is less than the parameter given. For numbers, this will ensure that the value is less than the parameter given.
@ -446,10 +504,18 @@ Example #1
Usage: lt=10 Usage: lt=10
Example #2 (time.Time) Example #2 (time.Time)
For time.Time ensures the time value is less than time.Now.UTC(). For time.Time ensures the time value is less than time.Now.UTC().
Usage: lt 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 Less Than or Equal
Same as 'max' above. Kept both to make terminology with 'len' easier. Same as 'max' above. Kept both to make terminology with 'len' easier.
@ -464,6 +530,13 @@ For time.Time ensures the time value is less than or equal to time.Now.UTC().
Usage: lte 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 Field Equals Another Field
This will validate the field value against another fields value either within This will validate the field value against another fields value either within
@ -510,9 +583,9 @@ relative to the top level struct.
Field Greater Than Another Field Field Greater Than Another Field
Only valid for Numbers and time.Time types, this will validate the field value Only valid for Numbers, time.Duration and time.Time types, this will validate
against another fields value either within a struct or passed in field. the field value against another fields value either within a struct or passed in
usage examples are for validation of a Start and End date: field. usage examples are for validation of a Start and End date:
Example #1: Example #1:
@ -524,7 +597,6 @@ Example #2:
// Validating by field: // Validating by field:
validate.VarWithValue(start, end, "gtfield") validate.VarWithValue(start, end, "gtfield")
Field Greater Than Another Relative Field Field Greater Than Another Relative Field
This does the same as gtfield except that it validates the field provided This does the same as gtfield except that it validates the field provided
@ -534,9 +606,9 @@ relative to the top level struct.
Field Greater Than or Equal To Another Field Field Greater Than or Equal To Another Field
Only valid for Numbers and time.Time types, this will validate the field value Only valid for Numbers, time.Duration and time.Time types, this will validate
against another fields value either within a struct or passed in field. the field value against another fields value either within a struct or passed in
usage examples are for validation of a Start and End date: field. usage examples are for validation of a Start and End date:
Example #1: Example #1:
@ -557,9 +629,9 @@ to the top level struct.
Less Than Another Field Less Than Another Field
Only valid for Numbers and time.Time types, this will validate the field value Only valid for Numbers, time.Duration and time.Time types, this will validate
against another fields value either within a struct or passed in field. the field value against another fields value either within a struct or passed in
usage examples are for validation of a Start and End date: field. usage examples are for validation of a Start and End date:
Example #1: Example #1:
@ -580,9 +652,9 @@ to the top level struct.
Less Than or Equal To Another Field Less Than or Equal To Another Field
Only valid for Numbers and time.Time types, this will validate the field value Only valid for Numbers, time.Duration and time.Time types, this will validate
against another fields value either within a struct or passed in field. the field value against another fields value either within a struct or passed in
usage examples are for validation of a Start and End date: field. usage examples are for validation of a Start and End date:
Example #1: Example #1:

@ -4,6 +4,7 @@ import (
"reflect" "reflect"
"strconv" "strconv"
"strings" "strings"
"time"
) )
// extractTypeInternal gets the actual underlying type of field value. // extractTypeInternal gets the actual underlying type of field value.
@ -229,6 +230,26 @@ func asInt(param string) int64 {
return i 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 // asUint returns the parameter as a uint64
// or panics if it can't convert // or panics if it can't convert
func asUint(param string) uint64 { func asUint(param string) uint64 {

@ -43,7 +43,9 @@ const (
) )
var ( var (
timeType = reflect.TypeOf(time.Time{}) timeDurationType = reflect.TypeOf(time.Duration(0))
timeType = reflect.TypeOf(time.Time{})
defaultCField = &cField{namesEqual: true} defaultCField = &cField{namesEqual: true}
) )

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save