duration.go raw
1 package retry
2
3 import (
4 "fmt"
5 "strings"
6 "time"
7 )
8
9 // Duration defines JSON marshal and unmarshal methods to conform to the
10 // protobuf JSON spec defined [here].
11 //
12 // [here]: https://protobuf.dev/reference/protobuf/google.protobuf/#duration
13 type Duration time.Duration
14
15 func (d Duration) String() string {
16 return fmt.Sprint(time.Duration(d))
17 }
18
19 // MarshalJSON converts from d to a JSON string output.
20 func (d Duration) MarshalJSON() ([]byte, error) {
21 ns := time.Duration(d).Nanoseconds()
22 sec := ns / int64(time.Second)
23 ns = ns % int64(time.Second)
24
25 var sign string
26 if sec < 0 || ns < 0 {
27 sign, sec, ns = "-", -1*sec, -1*ns
28 }
29
30 // Generated output always contains 0, 3, 6, or 9 fractional digits,
31 // depending on required precision.
32 str := fmt.Sprintf("%s%d.%09d", sign, sec, ns)
33 str = strings.TrimSuffix(str, "000")
34 str = strings.TrimSuffix(str, "000")
35 str = strings.TrimSuffix(str, ".000")
36
37 return []byte(fmt.Sprintf("\"%ss\"", str)), nil
38 }
39