21700: Install Bundler system-wide in Rails postinst
[arvados.git] / sdk / go / arvados / duration.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 package arvados
6
7 import (
8         "bytes"
9         "encoding/json"
10         "fmt"
11         "strings"
12         "time"
13 )
14
15 // Duration is time.Duration but looks like "12s" in JSON, rather than
16 // a number of nanoseconds.
17 type Duration time.Duration
18
19 // UnmarshalJSON implements json.Unmarshaler.
20 func (d *Duration) UnmarshalJSON(data []byte) error {
21         if bytes.Equal(data, []byte(`"0"`)) || bytes.Equal(data, []byte(`0`)) {
22                 // Unitless 0 is not accepted by ParseDuration, but we
23                 // accept it as a reasonable spelling of 0
24                 // nanoseconds.
25                 *d = 0
26                 return nil
27         }
28         if data[0] == '"' {
29                 return d.Set(string(data[1 : len(data)-1]))
30         }
31         // Mimic error message returned by ParseDuration for a number
32         // without units.
33         return fmt.Errorf("missing unit in duration %q", data)
34 }
35
36 // MarshalJSON implements json.Marshaler.
37 func (d Duration) MarshalJSON() ([]byte, error) {
38         return json.Marshal(d.String())
39 }
40
41 // String returns a format similar to (time.Duration)String() but with
42 // "0m" and "0s" removed: e.g., "1h" instead of "1h0m0s".
43 func (d Duration) String() string {
44         s := time.Duration(d).String()
45         s = strings.Replace(s, "m0s", "m", 1)
46         s = strings.Replace(s, "h0m", "h", 1)
47         return s
48 }
49
50 // Duration returns a time.Duration.
51 func (d Duration) Duration() time.Duration {
52         return time.Duration(d)
53 }
54
55 // Set implements the flag.Value interface and sets the duration value by using time.ParseDuration to parse the string.
56 func (d *Duration) Set(s string) error {
57         dur, err := time.ParseDuration(s)
58         *d = Duration(dur)
59         return err
60 }