OSDN Git Service

Hulk did something
[bytom/vapor.git] / encoding / json / duration.go
1 package json
2
3 import (
4         "bytes"
5         "encoding/json"
6         "errors"
7         "strconv"
8         "time"
9 )
10
11 type Duration struct {
12         time.Duration
13 }
14
15 // UnmarshalJSON fulfills the encoding/json.Unmarshaler interface.
16 // It attempts to parse text as a time.Duration string.
17 // The Go documentation defines this as a possibly signed sequence of decimal
18 // numbers, each with optional fraction and a unit suffix, such as
19 // "300ms", "-1.5h" or "2h45m".
20 // Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h").
21 // If there is no time unit, UnmarshalJSON defaults to ms.
22 func (d *Duration) UnmarshalJSON(b []byte) error {
23         if bytes.Equal(b, []byte("null")) {
24                 return nil
25         }
26
27         dMS, err := strconv.ParseInt(string(b), 10, 64)
28         if err != nil {
29                 // Assume this is a string instead, in which case we need to unmarshal it as a string
30                 // before we try to parse it as a time.Duration.
31                 var str string
32                 err = json.Unmarshal(b, &str)
33                 if err != nil {
34                         return errors.New("invalid json.Duration")
35                 }
36
37                 d0, err := time.ParseDuration(str)
38                 if err != nil {
39                         return errors.New("invalid json.Duration")
40                 }
41                 if d0 < 0 {
42                         return errors.New("invalid json.Duration: Duration cannot be less than 0")
43                 }
44                 d.Duration = d0
45         } else {
46                 if dMS < 0 {
47                         return errors.New("invalid json.Duration: Duration cannot be less than 0")
48                 }
49                 d.Duration = time.Duration(dMS) * time.Millisecond
50         }
51
52         return nil
53 }
54
55 // MarshalJSON implements json.Marshaler.
56 func (d Duration) MarshalJSON() ([]byte, error) {
57         return json.Marshal(d.Duration.Nanoseconds() / int64(time.Millisecond))
58 }