Merge branch '17395-container-output-storage-class' into main
[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         "encoding/json"
9         "fmt"
10         "strings"
11         "time"
12 )
13
14 // Duration is time.Duration but looks like "12s" in JSON, rather than
15 // a number of nanoseconds.
16 type Duration time.Duration
17
18 // UnmarshalJSON implements json.Unmarshaler.
19 func (d *Duration) UnmarshalJSON(data []byte) error {
20         if data[0] == '"' {
21                 return d.Set(string(data[1 : len(data)-1]))
22         }
23         // Mimic error message returned by ParseDuration for a number
24         // without units.
25         return fmt.Errorf("missing unit in duration %q", data)
26 }
27
28 // MarshalJSON implements json.Marshaler.
29 func (d Duration) MarshalJSON() ([]byte, error) {
30         return json.Marshal(d.String())
31 }
32
33 // String returns a format similar to (time.Duration)String() but with
34 // "0m" and "0s" removed: e.g., "1h" instead of "1h0m0s".
35 func (d Duration) String() string {
36         s := time.Duration(d).String()
37         s = strings.Replace(s, "m0s", "m", 1)
38         s = strings.Replace(s, "h0m", "h", 1)
39         return s
40 }
41
42 // Duration returns a time.Duration.
43 func (d Duration) Duration() time.Duration {
44         return time.Duration(d)
45 }
46
47 // Set implements the flag.Value interface and sets the duration value by using time.ParseDuration to parse the string.
48 func (d *Duration) Set(s string) error {
49         dur, err := time.ParseDuration(s)
50         *d = Duration(dur)
51         return err
52 }