-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathduration.go
125 lines (103 loc) · 2.72 KB
/
duration.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Copyright (c) Omlox Client Go Contributors
// SPDX-License-Identifier: MIT
package omlox
import (
"encoding/json"
"time"
easyjson "github.com/mailru/easyjson"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
const (
// Inf is the constant value representing infite.
Inf = -1
maxDuration time.Duration = 1<<63 - 1
)
var _ easyjson.Optional = (*Duration)(nil)
var _ easyjson.MarshalerUnmarshaler = (*Duration)(nil)
var _ json.Marshaler = (*Duration)(nil)
var _ json.Unmarshaler = (*Duration)(nil)
// Duration is an Omlox type that provides infinite semantics for a time duration.
// Must be a positive number or -1 in case of an infinite duration.
// All negative durations are considered infinite.
type Duration struct {
dur int
defined bool
}
// Create an infinite type of millisecond duration type.
func NewDuration(v int) Duration {
if v <= Inf {
return Duration{dur: Inf, defined: true}
}
return Duration{dur: v, defined: true}
}
// Inf return true on infinite value.
func (v Duration) Inf() bool {
return v.dur <= Inf
}
// MarshalEasyJSON does JSON marshaling using easyjson interface.
func (v Duration) MarshalEasyJSON(w *jwriter.Writer) {
if !v.defined {
w.RawString("null")
return
}
if v.dur <= Inf {
w.Int(Inf)
} else {
w.Int(v.dur)
}
}
// UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
func (v *Duration) UnmarshalEasyJSON(l *jlexer.Lexer) {
if l.IsNull() {
l.Skip()
*v = Duration{}
} else {
*v = NewDuration(l.Int())
}
}
// MarshalJSON implements a standard json marshaler interface.
// If the value is infinite, it will be ignored.
func (v Duration) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
v.MarshalEasyJSON(&w)
return w.Buffer.BuildBytes(), w.Error
}
// UnmarshalJSON implements a standard json unmarshaler interface.
func (v *Duration) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{Data: data}
v.UnmarshalEasyJSON(&l)
return l.Error()
}
// Duration returns a time.Duration.
// If its a infinite duration, it returns a maximum duration possible.
func (v *Duration) Duration() time.Duration {
if v.Inf() {
return maxDuration
}
return time.Duration(v.dur) * time.Millisecond
}
// IsDefined returns whether the value is defined.
// A function is required so that it can be used as [easyjson.Optional] interface.
func (v Duration) IsDefined() bool {
return v.defined
}
// String implements a stringer interface using fmt.Sprint for the value.
func (v Duration) String() string {
if v.Inf() {
return "<inf>"
}
return v.Duration().String()
}
func (v Duration) Equal(y Duration) bool {
if v.defined != y.defined {
return false
}
if v.Inf() && y.Inf() {
return true
}
if v.dur == y.dur {
return true
}
return false
}