-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: nicolaasuni-vonage <[email protected]>
- Loading branch information
1 parent
4189fd4
commit 6d3f399
Showing
9 changed files
with
350 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
1.75.9 | ||
1.76.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package timeutil | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"time" | ||
) | ||
|
||
// Duration is an alias for the standard time.Duration. | ||
type Duration time.Duration | ||
|
||
// String returns a string representing the duration in the form "72h3m0.5s". | ||
// It is a wrapper for time.Duration.String(). | ||
func (d Duration) String() string { | ||
return time.Duration(d).String() | ||
} | ||
|
||
// MarshalJSON returns d as the JSON encoding of d. | ||
// It encodes the time.Duration in human readable format (e.g.: 20s, 1h, ...). | ||
func (d Duration) MarshalJSON() ([]byte, error) { | ||
return json.Marshal(d.String()) //nolint:wrapcheck | ||
} | ||
|
||
// UnmarshalJSON sets *d to a copy of data. | ||
// It converts human readable time duration format (e.g.: 20s, 1h, ...) in standard time.Duration. | ||
func (d *Duration) UnmarshalJSON(data []byte) error { | ||
var v any | ||
|
||
if err := json.Unmarshal(data, &v); err != nil { | ||
return err //nolint:wrapcheck | ||
} | ||
|
||
switch value := v.(type) { | ||
case float64: | ||
*d = Duration(value) | ||
return nil | ||
case string: | ||
aux, err := time.ParseDuration(value) | ||
if err != nil { | ||
return fmt.Errorf("unable to parse the time duration %s :%w", value, err) | ||
} | ||
|
||
*d = Duration(aux) | ||
|
||
return nil | ||
default: | ||
return fmt.Errorf("invalid time duration type: %v", value) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,241 @@ | ||
package timeutil | ||
|
||
import ( | ||
"encoding/json" | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestDuration_MarshalJSON(t *testing.T) { | ||
t.Parallel() | ||
|
||
tests := []struct { | ||
name string | ||
dur Duration | ||
want []byte | ||
}{ | ||
{ | ||
name: "seconds", | ||
dur: Duration(13 * time.Second), | ||
want: []byte(`"13s"`), | ||
}, | ||
{ | ||
name: "minutes", | ||
dur: Duration(17 * time.Minute), | ||
want: []byte(`"17m0s"`), | ||
}, | ||
{ | ||
name: "hours", | ||
dur: Duration(7*time.Hour + 11*time.Minute + 13*time.Second), | ||
want: []byte(`"7h11m13s"`), | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
tt := tt | ||
t.Run(tt.name, func(t *testing.T) { | ||
t.Parallel() | ||
|
||
got, err := tt.dur.MarshalJSON() | ||
require.NoError(t, err) | ||
require.Equal(t, tt.want, got) | ||
}) | ||
} | ||
} | ||
|
||
func Test_json_Marshal(t *testing.T) { | ||
t.Parallel() | ||
|
||
type testData struct { | ||
Time Duration | ||
} | ||
|
||
tests := []struct { | ||
name string | ||
data testData | ||
want []byte | ||
}{ | ||
{ | ||
name: "seconds", | ||
data: testData{Time: Duration(13 * time.Second)}, | ||
want: []byte(`{"Time":"13s"}`), | ||
}, | ||
{ | ||
name: "minutes", | ||
data: testData{Time: Duration(17 * time.Minute)}, | ||
want: []byte(`{"Time":"17m0s"}`), | ||
}, | ||
{ | ||
name: "hours", | ||
data: testData{Time: Duration(7*time.Hour + 11*time.Minute + 13*time.Second)}, | ||
want: []byte(`{"Time":"7h11m13s"}`), | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
tt := tt | ||
t.Run(tt.name, func(t *testing.T) { | ||
t.Parallel() | ||
|
||
got, err := json.Marshal(tt.data) | ||
require.NoError(t, err) | ||
require.Equal(t, tt.want, got) | ||
}) | ||
} | ||
} | ||
|
||
func TestDuration_UnmarshalJSON(t *testing.T) { | ||
t.Parallel() | ||
|
||
tests := []struct { | ||
name string | ||
data []byte | ||
want Duration | ||
wantErr bool | ||
}{ | ||
{ | ||
name: "seconds", | ||
data: []byte(`"13s"`), | ||
want: Duration(13 * time.Second), | ||
}, | ||
{ | ||
name: "minutes", | ||
data: []byte(`"17m0s"`), | ||
want: Duration(17 * time.Minute), | ||
}, | ||
{ | ||
name: "hours", | ||
data: []byte(`"73h0m0s"`), | ||
want: Duration(73 * time.Hour), | ||
}, | ||
{ | ||
name: "number", | ||
data: []byte(`123456789`), | ||
want: Duration(123456789), | ||
}, | ||
{ | ||
name: "zero number", | ||
data: []byte(`0`), | ||
want: Duration(0), | ||
}, | ||
{ | ||
name: "negative number", | ||
data: []byte(`-17`), | ||
want: Duration(-17), | ||
}, | ||
{ | ||
name: "empty", | ||
data: []byte(``), | ||
wantErr: true, | ||
}, | ||
{ | ||
name: "empty string", | ||
data: []byte(`""`), | ||
wantErr: true, | ||
}, | ||
{ | ||
name: "invalid string", | ||
data: []byte(`"-"`), | ||
wantErr: true, | ||
}, | ||
{ | ||
name: "invalid type", | ||
data: []byte(`{"a":"b"}`), | ||
wantErr: true, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
tt := tt | ||
t.Run(tt.name, func(t *testing.T) { | ||
t.Parallel() | ||
|
||
var dur Duration | ||
|
||
err := dur.UnmarshalJSON(tt.data) | ||
require.Equal(t, tt.wantErr, err != nil, "error = %v, wantErr %v", err, tt.wantErr) | ||
require.Equal(t, int64(tt.want), int64(dur)) | ||
}) | ||
} | ||
} | ||
|
||
func Test_json_Unmarshal(t *testing.T) { | ||
t.Parallel() | ||
|
||
type testData struct { | ||
Time Duration | ||
} | ||
|
||
tests := []struct { | ||
name string | ||
data []byte | ||
want Duration | ||
wantErr bool | ||
}{ | ||
{ | ||
name: "seconds", | ||
data: []byte(`{"Time":"13s"}`), | ||
want: Duration(13 * time.Second), | ||
}, | ||
{ | ||
name: "minutes", | ||
data: []byte(`{"Time":"17m0s"}`), | ||
want: Duration(17 * time.Minute), | ||
}, | ||
{ | ||
name: "hours", | ||
data: []byte(`{"Time":"7h11m13s"}`), | ||
want: Duration(7*time.Hour + 11*time.Minute + 13*time.Second), | ||
}, | ||
{ | ||
name: "number", | ||
data: []byte(`{"Time":123456789}`), | ||
want: Duration(123456789), | ||
}, | ||
{ | ||
name: "zero number", | ||
data: []byte(`{"Time":0}`), | ||
want: Duration(0), | ||
}, | ||
{ | ||
name: "negative number", | ||
data: []byte(`{"Time":-17}`), | ||
want: Duration(-17), | ||
}, | ||
{ | ||
name: "null", | ||
data: []byte(`{"Time":null}`), | ||
wantErr: true, | ||
}, | ||
{ | ||
name: "empty string", | ||
data: []byte(`{"Time":""}`), | ||
wantErr: true, | ||
}, | ||
{ | ||
name: "invalid string", | ||
data: []byte(`{"Time":"-"}`), | ||
wantErr: true, | ||
}, | ||
{ | ||
name: "invalid type", | ||
data: []byte(`{"Time":{"a":"b"}}`), | ||
wantErr: true, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
tt := tt | ||
t.Run(tt.name, func(t *testing.T) { | ||
t.Parallel() | ||
|
||
var d testData | ||
|
||
err := json.Unmarshal(tt.data, &d) | ||
require.Equal(t, tt.wantErr, err != nil, "error = %v, wantErr %v", err, tt.wantErr) | ||
require.Equal(t, int64(tt.want), int64(d.Time)) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package timeutil_test | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"log" | ||
"time" | ||
|
||
"github.com/Vonage/gosrvlib/pkg/timeutil" | ||
) | ||
|
||
func ExampleDuration_MarshalJSON() { | ||
type testData struct { | ||
Time timeutil.Duration | ||
} | ||
|
||
data := testData{ | ||
Time: timeutil.Duration(7*time.Hour + 11*time.Minute + 13*time.Second), | ||
} | ||
|
||
enc, err := json.Marshal(data) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
fmt.Println(string(enc)) | ||
|
||
// Output: | ||
// {"Time":"7h11m13s"} | ||
} | ||
|
||
func ExampleDuration_UnmarshalJSON() { | ||
type testData struct { | ||
Time timeutil.Duration | ||
} | ||
|
||
enc := []byte(`{"Time":"7h11m13s"}`) | ||
|
||
var data testData | ||
|
||
err := json.Unmarshal(enc, &data) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
fmt.Println(data.Time.String()) | ||
|
||
// Output: | ||
// 7h11m13s | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// Package timeutil adds utility functions to the standard time library. | ||
package timeutil |