From 8768b7dbdfa16c5f0b435c7fe72b15ef135968e4 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Wed, 7 Aug 2024 02:48:44 +0800 Subject: [PATCH] add json support to Pointer (#180) * add json support to Pointer * update changelog * coverage --- CHANGELOG.md | 4 +++- pointer_go118.go | 20 +++++++++++++++++++- pointer_test.go | 27 ++++++++++++++++++++++++++- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71db542..2e987a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## Unreleased -- No changes yet. +### Added +- Add `MarshalJSON` and `UnmarshalJSON` method to `atomic.Pointer[T]` type +allowing users to use pointer with json. ## [1.11.0] - 2023-05-02 ### Fixed diff --git a/pointer_go118.go b/pointer_go118.go index 1fb6c03..fb7e124 100644 --- a/pointer_go118.go +++ b/pointer_go118.go @@ -23,9 +23,27 @@ package atomic -import "fmt" +import ( + "encoding/json" + "fmt" +) // String returns a human readable representation of a Pointer's underlying value. func (p *Pointer[T]) String() string { return fmt.Sprint(p.Load()) } + +// MarshalJSON encodes the wrapped pointer into JSON. +func (p *Pointer[T]) MarshalJSON() ([]byte, error) { + return json.Marshal(p.Load()) +} + +// UnmarshalJSON decodes JSON into the wrapped pointer. +func (p *Pointer[T]) UnmarshalJSON(b []byte) error { + var v T + if err := json.Unmarshal(b, &v); err != nil { + return err + } + p.Store(&v) + return nil +} diff --git a/pointer_test.go b/pointer_test.go index 7d2d32b..edb2d41 100644 --- a/pointer_test.go +++ b/pointer_test.go @@ -24,6 +24,7 @@ package atomic import ( + "encoding/json" "fmt" "testing" @@ -31,7 +32,9 @@ import ( ) func TestPointer(t *testing.T) { - type foo struct{ v int } + type foo struct { + V int `json:"v"` + } i := foo{42} j := foo{0} @@ -94,6 +97,28 @@ func TestPointer(t *testing.T) { atom := tt.newAtomic() require.Equal(t, fmt.Sprint(tt.initial), atom.String(), "String did not return the correct value.") }) + + t.Run("MarshalJSON", func(t *testing.T) { + atom := tt.newAtomic() + marshaledPointer, err := json.Marshal(atom) + require.NoError(t, err) + marshaledRaw, err := json.Marshal(tt.initial) + require.NoError(t, err) + require.Equal(t, marshaledRaw, marshaledPointer, "MarshalJSON did not return the correct value.") + }) }) } + + t.Run("UnmarshalJSON", func(t *testing.T) { + var p Pointer[foo] + + require.NoError(t, json.Unmarshal([]byte(`{"v":1024}`), &p)) + require.Equal(t, 1024, p.Load().V, "UnmarshalJSON should have expected result") + }) + + t.Run("UnmarshalJSON error", func(t *testing.T) { + var p Pointer[foo] + + require.Error(t, json.Unmarshal([]byte(`{"v":true}`), &p), "json.Unmarshal should return an error") + }) }