1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package strfmt
16
17 import (
18 "encoding/json"
19 "fmt"
20 "regexp"
21 "strconv"
22 "strings"
23 "time"
24 )
25
26 func init() {
27 d := Duration(0)
28
29 Default.Add("duration", &d, IsDuration)
30 }
31
32 var (
33 timeUnits = [][]string{
34 {"ns", "nano"},
35 {"us", "µs", "micro"},
36 {"ms", "milli"},
37 {"s", "sec"},
38 {"m", "min"},
39 {"h", "hr", "hour"},
40 {"d", "day"},
41 {"w", "wk", "week"},
42 }
43
44 timeMultiplier = map[string]time.Duration{
45 "ns": time.Nanosecond,
46 "us": time.Microsecond,
47 "ms": time.Millisecond,
48 "s": time.Second,
49 "m": time.Minute,
50 "h": time.Hour,
51 "d": 24 * time.Hour,
52 "w": 7 * 24 * time.Hour,
53 }
54
55 durationMatcher = regexp.MustCompile(`((\d+)\s*([A-Za-zµ]+))`)
56 )
57
58
59 func IsDuration(str string) bool {
60 _, err := ParseDuration(str)
61 return err == nil
62 }
63
64
65
66
67
68
69
70 type Duration time.Duration
71
72
73 func (d Duration) MarshalText() ([]byte, error) {
74 return []byte(time.Duration(d).String()), nil
75 }
76
77
78 func (d *Duration) UnmarshalText(data []byte) error {
79 dd, err := ParseDuration(string(data))
80 if err != nil {
81 return err
82 }
83 *d = Duration(dd)
84 return nil
85 }
86
87
88 func ParseDuration(cand string) (time.Duration, error) {
89 if dur, err := time.ParseDuration(cand); err == nil {
90 return dur, nil
91 }
92
93 var dur time.Duration
94 ok := false
95 for _, match := range durationMatcher.FindAllStringSubmatch(cand, -1) {
96
97 factor, err := strconv.Atoi(match[2])
98 if err != nil {
99 return 0, err
100 }
101 unit := strings.ToLower(strings.TrimSpace(match[3]))
102
103 for _, variants := range timeUnits {
104 last := len(variants) - 1
105 multiplier := timeMultiplier[variants[0]]
106
107 for i, variant := range variants {
108 if (last == i && strings.HasPrefix(unit, variant)) || strings.EqualFold(variant, unit) {
109 ok = true
110 dur += time.Duration(factor) * multiplier
111 }
112 }
113 }
114 }
115
116 if ok {
117 return dur, nil
118 }
119 return 0, fmt.Errorf("unable to parse %s as duration", cand)
120 }
121
122
123 func (d *Duration) Scan(raw interface{}) error {
124 switch v := raw.(type) {
125
126 case int64:
127 *d = Duration(v)
128 case float64:
129 *d = Duration(int64(v))
130 case nil:
131 *d = Duration(0)
132 default:
133 return fmt.Errorf("cannot sql.Scan() strfmt.Duration from: %#v", v)
134 }
135
136 return nil
137 }
138
139
140 func (d Duration) String() string {
141 return time.Duration(d).String()
142 }
143
144
145 func (d Duration) MarshalJSON() ([]byte, error) {
146 return json.Marshal(time.Duration(d).String())
147 }
148
149
150 func (d *Duration) UnmarshalJSON(data []byte) error {
151 if string(data) == jsonNull {
152 return nil
153 }
154
155 var dstr string
156 if err := json.Unmarshal(data, &dstr); err != nil {
157 return err
158 }
159 tt, err := ParseDuration(dstr)
160 if err != nil {
161 return err
162 }
163 *d = Duration(tt)
164 return nil
165 }
166
167
168 func (d *Duration) DeepCopyInto(out *Duration) {
169 *out = *d
170 }
171
172
173 func (d *Duration) DeepCopy() *Duration {
174 if d == nil {
175 return nil
176 }
177 out := new(Duration)
178 d.DeepCopyInto(out)
179 return out
180 }
181
View as plain text