Skip to content

Commit 96529dc

Browse files
authored
Merge pull request #76 from strongdm/native-go-datetime-duration-converters
types: add go native conversion methods to several types
2 parents 38eae78 + 84ee8af commit 96529dc

7 files changed

+65
-0
lines changed

internal/error.go

+1
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ var ErrDecimal = fmt.Errorf("error parsing decimal value")
1111
var ErrDuration = fmt.Errorf("error parsing duration value")
1212
var ErrIP = fmt.Errorf("error parsing ip value")
1313
var ErrNotComparable = fmt.Errorf("incompatible types in comparison")
14+
var ErrDurationRange = fmt.Errorf("duration out of range")

types/datetime.go

+5
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,11 @@ func (a Datetime) Milliseconds() int64 {
274274
return a.value
275275
}
276276

277+
// Time returns the UTC time.Time representation of a Datetime.
278+
func (a Datetime) Time() time.Time {
279+
return time.UnixMilli(a.value).UTC()
280+
}
281+
277282
func (v Datetime) hash() uint64 {
278283
return uint64(v.value)
279284
}

types/datetime_test.go

+8
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,14 @@ func TestDatetime(t *testing.T) {
119119
testutil.Equals(t, one.Milliseconds(), two.Milliseconds())
120120
})
121121

122+
t.Run("Time", func(t *testing.T) {
123+
t.Parallel()
124+
in := types.NewDatetime(time.UnixMilli(42))
125+
got := in.Time()
126+
want := time.UnixMilli(42).UTC()
127+
testutil.Equals(t, got, want)
128+
})
129+
122130
t.Run("Equal", func(t *testing.T) {
123131
t.Parallel()
124132
one := types.NewDatetimeFromMillis(1)

types/decimal.go

+6
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ func (d Decimal) MarshalJSON() ([]byte, error) {
186186
})
187187
}
188188

189+
// Float returns a float64 representation of a Decimal. Warning: some precision
190+
// may be lost during this conversion.
191+
func (d Decimal) Float() float64 {
192+
return float64(d.value) / decimalPrecision
193+
}
194+
189195
func (d Decimal) hash() uint64 {
190196
return uint64(d.value)
191197
}

types/decimal_test.go

+9
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,15 @@ func TestDecimal(t *testing.T) {
281281
}
282282
})
283283

284+
t.Run("Float", func(t *testing.T) {
285+
t.Parallel()
286+
in, err := types.NewDecimalFromFloat(42.42)
287+
testutil.OK(t, err)
288+
got := in.Float()
289+
want := 42.42
290+
testutil.Equals(t, got, want)
291+
})
292+
284293
t.Run("MarshalCedar", func(t *testing.T) {
285294
t.Parallel()
286295
testutil.Equals(

types/duration.go

+12
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,18 @@ func (v Duration) ToMilliseconds() int64 {
267267
return v.value
268268
}
269269

270+
// Duration returns a time.Duration representation of a Duration. An error
271+
// is returned if the duration cannot be converted to a time.Duration.
272+
func (v Duration) Duration() (time.Duration, error) {
273+
if v.value > math.MaxInt64/1000 {
274+
return 0, internal.ErrDurationRange
275+
}
276+
if v.value < math.MinInt64/1000 {
277+
return 0, internal.ErrDurationRange
278+
}
279+
return time.Millisecond * time.Duration(v.value), nil
280+
}
281+
270282
func (v Duration) hash() uint64 {
271283
return uint64(v.value)
272284
}

types/duration_test.go

+24
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package types_test
33
import (
44
"encoding/json"
55
"fmt"
6+
"math"
67
"testing"
78
"time"
89

@@ -87,6 +88,29 @@ func TestDuration(t *testing.T) {
8788
testutil.Equals(t, one.ToMilliseconds(), two.ToMilliseconds())
8889
})
8990

91+
t.Run("Duration", func(t *testing.T) {
92+
t.Parallel()
93+
tests := []struct {
94+
name string
95+
in types.Duration
96+
out time.Duration
97+
err func(testutil.TB, error)
98+
}{
99+
{"ok", types.NewDuration(time.Millisecond * 42), time.Millisecond * 42, testutil.OK},
100+
{"maxPlusOne", types.NewDurationFromMillis(math.MaxInt64/1000 + 1), 0, testutil.Error},
101+
{"minMinusOne", types.NewDurationFromMillis(math.MinInt64/1000 - 1), 0, testutil.Error},
102+
}
103+
for _, tt := range tests {
104+
tt := tt
105+
t.Run(tt.name, func(t *testing.T) {
106+
t.Parallel()
107+
out, err := tt.in.Duration()
108+
testutil.Equals(t, out, tt.out)
109+
tt.err(t, err)
110+
})
111+
}
112+
})
113+
90114
t.Run("Equal", func(t *testing.T) {
91115
t.Parallel()
92116
one := types.NewDurationFromMillis(1)

0 commit comments

Comments
 (0)