Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Add `String` method to `atomic.Pointer[T]` type allowing users to safely print
underlying values of pointers.
- Support JSON serialization and deserialization of `atomic.Time`

## [1.10.0] - 2022-08-11
### Added
Expand Down
16 changes: 16 additions & 0 deletions time.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
package atomic

import (
"encoding/json"
"time"
)

Expand Down Expand Up @@ -53,3 +54,18 @@ func (x *Time) Load() time.Time {
func (x *Time) Store(val time.Time) {
x.v.Store(packTime(val))
}

// MarshalJSON encodes the wrapped time.Time into JSON.
func (x *Time) MarshalJSON() ([]byte, error) {
return json.Marshal(x.Load())
}

// UnmarshalJSON decodes a time.Time from JSON.
func (x *Time) UnmarshalJSON(b []byte) error {
var v time.Time
if err := json.Unmarshal(b, &v); err != nil {
return err
}
x.Store(v)
return nil
}
2 changes: 1 addition & 1 deletion time_ext.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ package atomic

import "time"

//go:generate bin/gen-atomicwrapper -name=Time -type=time.Time -wrapped=Value -pack=packTime -unpack=unpackTime -imports time -file=time.go
//go:generate bin/gen-atomicwrapper -name=Time -type=time.Time -wrapped=Value -pack=packTime -unpack=unpackTime -json -imports time -file=time.go

func packTime(t time.Time) interface{} {
return t
Expand Down
26 changes: 26 additions & 0 deletions time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package atomic

import (
"encoding/json"
"testing"
"time"

Expand Down Expand Up @@ -71,6 +72,31 @@ func TestLargeTime(t *testing.T) {
atom.Store(dayBeforePast)
assert.Equal(t, 1677, atom.Load().Year())
})

t.Run("JSON/Marshal", func(t *testing.T) {
now := time.Now()
atom := NewTime(now)
bytes, err := json.Marshal(atom)
require.NoError(t, err, "json.Marshal errored unexpectedly.")

oBytes, err := json.Marshal(now)
require.NoError(t, err, "json.Marshal errored unexpectedly on the native time.Time.")
require.Equal(t, oBytes, bytes, "json.Marshal encoded the wrong bytes.")
})

t.Run("JSON/Unmarshal", func(t *testing.T) {
now := time.Now()
atom := NewTime(time.Time{})

oBytes, err := json.Marshal(now)
require.NoError(t, err, "json.Marshal errored unexpectedly on the native time.Time.")
err = json.Unmarshal(oBytes, &atom)
require.NoError(t, err, "json.Unmarshal errored unexpectedly.")
// NOTE: https://pkg.go.dev/time#Time.MarshalJSON, the time is formatted as RFC 3339
// example: 2022-11-25T21:06:44.6023404+01:00
// So we cannot compare now and atom.Load() because we lack nanoseconds
require.Equal(t, now.UnixMicro(), atom.Load().UnixMicro(), "json.Unmarshal didn't set the correct value.")
})
}

func TestMonotonic(t *testing.T) {
Expand Down