Skip to content

Commit 76981cc

Browse files
author
Dean Karn
authored
Merge pull request #642 from elias19r/issue-584-add-support-for-time-duration-type
Add support for time.Duration type
2 parents 57b4fab + 1cbd308 commit 76981cc

File tree

6 files changed

+1321
-78
lines changed

6 files changed

+1321
-78
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
# Folders
77
_obj
88
_test
9+
bin
910

1011
# Architecture specific extensions/prefixes
1112
*.[568vq]
@@ -26,4 +27,4 @@ _testmain.go
2627
*.out
2728
*.txt
2829
cover.html
29-
README.html
30+
README.html

baked_in.go

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,7 +1145,7 @@ func isEq(fl FieldLevel) bool {
11451145
return int64(field.Len()) == p
11461146

11471147
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
1148-
p := asInt(param)
1148+
p := asIntFromType(field.Type(), param)
11491149

11501150
return field.Int() == p
11511151

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

16611661
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
1662-
p := asInt(param)
1662+
p := asIntFromType(field.Type(), param)
16631663

16641664
return field.Int() >= p
16651665

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

17081708
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
1709-
p := asInt(param)
1709+
p := asIntFromType(field.Type(), param)
17101710

17111711
return field.Int() > p
17121712

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

17511751
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
1752-
p := asInt(param)
1752+
p := asIntFromType(field.Type(), param)
17531753

17541754
return field.Int() == p
17551755

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

18871887
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
1888-
p := asInt(param)
1888+
p := asIntFromType(field.Type(), param)
18891889

18901890
return field.Int() <= p
18911891

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

19341934
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
1935-
p := asInt(param)
1935+
p := asIntFromType(field.Type(), param)
19361936

19371937
return field.Int() < p
19381938

@@ -2205,11 +2205,8 @@ func isDatetime(fl FieldLevel) bool {
22052205

22062206
if field.Kind() == reflect.String {
22072207
_, err := time.Parse(param, field.String())
2208-
if err != nil {
2209-
return false
2210-
}
22112208

2212-
return true
2209+
return err == nil
22132210
}
22142211

22152212
panic(fmt.Sprintf("Bad field type %T", field.Interface()))

doc.go

Lines changed: 86 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -355,42 +355,87 @@ equal to the parameter given. For strings, it checks that
355355
the string length is exactly that number of characters. For slices,
356356
arrays, and maps, validates the number of items.
357357
358+
Example #1
359+
358360
Usage: len=10
359361
362+
Example #2 (time.Duration)
363+
364+
For time.Duration, len will ensure that the value is equal to the duration given
365+
in the parameter.
366+
367+
Usage: len=1h30m
368+
360369
Maximum
361370
362371
For numbers, max will ensure that the value is
363372
less than or equal to the parameter given. For strings, it checks
364373
that the string length is at most that number of characters. For
365374
slices, arrays, and maps, validates the number of items.
366375
376+
Example #1
377+
367378
Usage: max=10
368379
380+
Example #2 (time.Duration)
381+
382+
For time.Duration, max will ensure that the value is less than or equal to the
383+
duration given in the parameter.
384+
385+
Usage: max=1h30m
386+
369387
Minimum
370388
371389
For numbers, min will ensure that the value is
372390
greater or equal to the parameter given. For strings, it checks that
373391
the string length is at least that number of characters. For slices,
374392
arrays, and maps, validates the number of items.
375393
394+
Example #1
395+
376396
Usage: min=10
377397
398+
Example #2 (time.Duration)
399+
400+
For time.Duration, min will ensure that the value is greater than or equal to
401+
the duration given in the parameter.
402+
403+
Usage: min=1h30m
404+
378405
Equals
379406
380407
For strings & numbers, eq will ensure that the value is
381408
equal to the parameter given. For slices, arrays, and maps,
382409
validates the number of items.
383410
411+
Example #1
412+
384413
Usage: eq=10
385414
415+
Example #2 (time.Duration)
416+
417+
For time.Duration, eq will ensure that the value is equal to the duration given
418+
in the parameter.
419+
420+
Usage: eq=1h30m
421+
386422
Not Equal
387423
388424
For strings & numbers, ne will ensure that the value is not
389425
equal to the parameter given. For slices, arrays, and maps,
390426
validates the number of items.
391427
428+
Example #1
429+
392430
Usage: ne=10
393431
432+
Example #2 (time.Duration)
433+
434+
For time.Duration, ne will ensure that the value is not equal to the duration
435+
given in the parameter.
436+
437+
Usage: ne=1h30m
438+
394439
One Of
395440
396441
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().
420465
421466
Usage: gt
422467
468+
Example #3 (time.Duration)
469+
470+
For time.Duration, gt will ensure that the value is greater than the duration
471+
given in the parameter.
472+
473+
Usage: gt=1h30m
474+
423475
Greater Than or Equal
424476
425477
Same as 'min' above. Kept both to make terminology with 'len' easier.
426478
427-
428479
Example #1
429480
430481
Usage: gte=10
@@ -435,6 +486,13 @@ For time.Time ensures the time value is greater than or equal to time.Now.UTC().
435486
436487
Usage: gte
437488
489+
Example #3 (time.Duration)
490+
491+
For time.Duration, gte will ensure that the value is greater than or equal to
492+
the duration given in the parameter.
493+
494+
Usage: gte=1h30m
495+
438496
Less Than
439497
440498
For numbers, this will ensure that the value is less than the parameter given.
@@ -446,10 +504,18 @@ Example #1
446504
Usage: lt=10
447505
448506
Example #2 (time.Time)
507+
449508
For time.Time ensures the time value is less than time.Now.UTC().
450509
451510
Usage: lt
452511
512+
Example #3 (time.Duration)
513+
514+
For time.Duration, lt will ensure that the value is less than the duration given
515+
in the parameter.
516+
517+
Usage: lt=1h30m
518+
453519
Less Than or Equal
454520
455521
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().
464530
465531
Usage: lte
466532
533+
Example #3 (time.Duration)
534+
535+
For time.Duration, lte will ensure that the value is less than or equal to the
536+
duration given in the parameter.
537+
538+
Usage: lte=1h30m
539+
467540
Field Equals Another Field
468541
469542
This will validate the field value against another fields value either within
@@ -510,9 +583,9 @@ relative to the top level struct.
510583
511584
Field Greater Than Another Field
512585
513-
Only valid for Numbers and time.Time types, this will validate the field value
514-
against another fields value either within a struct or passed in field.
515-
usage examples are for validation of a Start and End date:
586+
Only valid for Numbers, time.Duration and time.Time types, this will validate
587+
the field value against another fields value either within a struct or passed in
588+
field. usage examples are for validation of a Start and End date:
516589
517590
Example #1:
518591
@@ -524,7 +597,6 @@ Example #2:
524597
// Validating by field:
525598
validate.VarWithValue(start, end, "gtfield")
526599
527-
528600
Field Greater Than Another Relative Field
529601
530602
This does the same as gtfield except that it validates the field provided
@@ -534,9 +606,9 @@ relative to the top level struct.
534606
535607
Field Greater Than or Equal To Another Field
536608
537-
Only valid for Numbers and time.Time types, this will validate the field value
538-
against another fields value either within a struct or passed in field.
539-
usage examples are for validation of a Start and End date:
609+
Only valid for Numbers, time.Duration and time.Time types, this will validate
610+
the field value against another fields value either within a struct or passed in
611+
field. usage examples are for validation of a Start and End date:
540612
541613
Example #1:
542614
@@ -557,9 +629,9 @@ to the top level struct.
557629
558630
Less Than Another Field
559631
560-
Only valid for Numbers and time.Time types, this will validate the field value
561-
against another fields value either within a struct or passed in field.
562-
usage examples are for validation of a Start and End date:
632+
Only valid for Numbers, time.Duration and time.Time types, this will validate
633+
the field value against another fields value either within a struct or passed in
634+
field. usage examples are for validation of a Start and End date:
563635
564636
Example #1:
565637
@@ -580,9 +652,9 @@ to the top level struct.
580652
581653
Less Than or Equal To Another Field
582654
583-
Only valid for Numbers and time.Time types, this will validate the field value
584-
against another fields value either within a struct or passed in field.
585-
usage examples are for validation of a Start and End date:
655+
Only valid for Numbers, time.Duration and time.Time types, this will validate
656+
the field value against another fields value either within a struct or passed in
657+
field. usage examples are for validation of a Start and End date:
586658
587659
Example #1:
588660

util.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"reflect"
55
"strconv"
66
"strings"
7+
"time"
78
)
89

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

233+
// asIntFromTimeDuration parses param as time.Duration and returns it as int64
234+
// or panics on error.
235+
func asIntFromTimeDuration(param string) int64 {
236+
d, err := time.ParseDuration(param)
237+
panicIf(err)
238+
239+
return int64(d)
240+
}
241+
242+
// asIntFromType calls the proper function to parse param as int64,
243+
// given a field's Type t.
244+
func asIntFromType(t reflect.Type, param string) int64 {
245+
switch t {
246+
case timeDurationType:
247+
return asIntFromTimeDuration(param)
248+
default:
249+
return asInt(param)
250+
}
251+
}
252+
232253
// asUint returns the parameter as a uint64
233254
// or panics if it can't convert
234255
func asUint(param string) uint64 {

validator_instance.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ const (
4343
)
4444

4545
var (
46-
timeType = reflect.TypeOf(time.Time{})
46+
timeDurationType = reflect.TypeOf(time.Duration(0))
47+
timeType = reflect.TypeOf(time.Time{})
48+
4749
defaultCField = &cField{namesEqual: true}
4850
)
4951

0 commit comments

Comments
 (0)