Skip to content

Commit

Permalink
Add MarshalJSON to sync types (#121)
Browse files Browse the repository at this point in the history
  • Loading branch information
GerardRodes authored Jul 7, 2022
1 parent 8394828 commit d1bb448
Show file tree
Hide file tree
Showing 2 changed files with 200 additions and 1 deletion.
99 changes: 98 additions & 1 deletion sync/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package sync

import (
"bytes"
"encoding/json"
"fmt"
"strconv"
"strings"
Expand Down Expand Up @@ -30,6 +31,20 @@ func (b *Bool) Set(value bool) {
b.value = value
}

// MarshalJSON returns the JSON encoding of the value.
func (b *Bool) MarshalJSON() ([]byte, error) {
b.rw.RLock()
defer b.rw.RUnlock()
return json.Marshal(b.value)
}

// MarshalJSON returns the JSON encoding of the value.
func (b *Bool) UnmarshalJSON(d []byte) error {
b.rw.RLock()
defer b.rw.RUnlock()
return json.Unmarshal(d, &b.value)
}

// String returns string representation of value.
func (b *Bool) String() string {
b.rw.Lock()
Expand Down Expand Up @@ -70,6 +85,20 @@ func (i *Int64) Set(value int64) {
i.value = value
}

// MarshalJSON returns the JSON encoding of the value.
func (i *Int64) MarshalJSON() ([]byte, error) {
i.rw.RLock()
defer i.rw.RUnlock()
return json.Marshal(i.value)
}

// MarshalJSON returns the JSON encoding of the value.
func (i *Int64) UnmarshalJSON(d []byte) error {
i.rw.RLock()
defer i.rw.RUnlock()
return json.Unmarshal(d, &i.value)
}

// String returns string representation of value.
func (i *Int64) String() string {
i.rw.RLock()
Expand Down Expand Up @@ -107,6 +136,20 @@ func (f *Float64) Set(value float64) {
f.value = value
}

// MarshalJSON returns the JSON encoding of the value.
func (f *Float64) MarshalJSON() ([]byte, error) {
f.rw.RLock()
defer f.rw.RUnlock()
return json.Marshal(f.value)
}

// MarshalJSON returns the JSON encoding of the value.
func (f *Float64) UnmarshalJSON(d []byte) error {
f.rw.RLock()
defer f.rw.RUnlock()
return json.Unmarshal(d, &f.value)
}

// String returns string representation of value.
func (f *Float64) String() string {
f.rw.RLock()
Expand Down Expand Up @@ -144,6 +187,20 @@ func (s *String) Set(value string) {
s.value = value
}

// MarshalJSON returns the JSON encoding of the value.
func (s *String) MarshalJSON() ([]byte, error) {
s.rw.RLock()
defer s.rw.RUnlock()
return json.Marshal(s.value)
}

// MarshalJSON returns the JSON encoding of the value.
func (s *String) UnmarshalJSON(d []byte) error {
s.rw.RLock()
defer s.rw.RUnlock()
return json.Unmarshal(d, &s.value)
}

// String returns string representation of value.
func (s *String) String() string {
s.rw.RLock()
Expand Down Expand Up @@ -177,6 +234,20 @@ func (s *TimeDuration) Set(value time.Duration) {
s.value = value
}

// MarshalJSON returns the JSON encoding of the value.
func (s *TimeDuration) MarshalJSON() ([]byte, error) {
s.rw.RLock()
defer s.rw.RUnlock()
return json.Marshal(s.value)
}

// MarshalJSON returns the JSON encoding of the value.
func (s *TimeDuration) UnmarshalJSON(d []byte) error {
s.rw.RLock()
defer s.rw.RUnlock()
return json.Unmarshal(d, &s.value)
}

// String returns string representation of value.
func (s *TimeDuration) String() string {
s.rw.RLock()
Expand Down Expand Up @@ -214,6 +285,18 @@ func (s *Secret) Set(value string) {
s.value = value
}

// MarshalJSON returns the JSON encoding of the value.
func (s *Secret) MarshalJSON() (out []byte, err error) {
return json.Marshal(s.String())
}

// MarshalJSON returns the JSON encoding of the value.
func (s *Secret) UnmarshalJSON(d []byte) error {
s.rw.RLock()
defer s.rw.RUnlock()
return json.Unmarshal(d, &s.value)
}

// String returns obfuscated string representation of value.
func (s *Secret) String() string {
return "***"
Expand Down Expand Up @@ -245,7 +328,21 @@ func (s *StringMap) Set(value map[string]string) {
s.value = value
}

// String returns a string representation of the value.
// MarshalJSON returns the JSON encoding of the value.
func (s *StringMap) MarshalJSON() ([]byte, error) {
s.rw.RLock()
defer s.rw.RUnlock()
return json.Marshal(s.value)
}

// MarshalJSON returns the JSON encoding of the value.
func (s *StringMap) UnmarshalJSON(d []byte) error {
s.rw.RLock()
defer s.rw.RUnlock()
return json.Unmarshal(d, &s.value)
}

// String returns a string representation of the value..
func (s *StringMap) String() string {
s.rw.RLock()
defer s.rw.RUnlock()
Expand Down
102 changes: 102 additions & 0 deletions sync/sync_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package sync

import (
"fmt"
"testing"
"time"

Expand All @@ -17,6 +18,10 @@ func TestBool(t *testing.T) {
<-ch
assert.True(t, b.Get())
assert.Equal(t, "true", b.String())

d, err := b.MarshalJSON()
assert.NoError(t, err)
assert.Equal(t, "true", string(d))
}

func TestBool_SetString(t *testing.T) {
Expand All @@ -26,6 +31,17 @@ func TestBool_SetString(t *testing.T) {
assert.True(t, b.Get())
}

func TestBool_UnmarshalJSON(t *testing.T) {
var b Bool
err := b.UnmarshalJSON([]byte("wrong"))
assert.Error(t, err)
assert.False(t, b.Get())

err = b.UnmarshalJSON([]byte("true"))
assert.NoError(t, err)
assert.True(t, b.Get())
}

func TestInt64(t *testing.T) {
var i Int64
ch := make(chan struct{})
Expand All @@ -36,6 +52,10 @@ func TestInt64(t *testing.T) {
<-ch
assert.Equal(t, int64(10), i.Get())
assert.Equal(t, "10", i.String())

d, err := i.MarshalJSON()
assert.NoError(t, err)
assert.Equal(t, "10", string(d))
}

func TestInt64_SetString(t *testing.T) {
Expand All @@ -45,6 +65,17 @@ func TestInt64_SetString(t *testing.T) {
assert.Equal(t, int64(10), i.Get())
}

func TestInt64_UnmarshalJSON(t *testing.T) {
var b Int64
err := b.UnmarshalJSON([]byte("123.544")) // this is wrong
assert.Error(t, err)
assert.Equal(t, int64(0), b.Get())

err = b.UnmarshalJSON([]byte("123"))
assert.NoError(t, err)
assert.Equal(t, int64(123), b.Get())
}

func TestFloat64(t *testing.T) {
var f Float64
ch := make(chan struct{})
Expand All @@ -55,6 +86,21 @@ func TestFloat64(t *testing.T) {
<-ch
assert.Equal(t, 1.23, f.Get())
assert.Equal(t, "1.230000", f.String())

d, err := f.MarshalJSON()
assert.NoError(t, err)
assert.Equal(t, "1.23", string(d))
}

func TestFloat64_UnmarshalJSON(t *testing.T) {
var b Float64
err := b.UnmarshalJSON([]byte("wrong"))
assert.Error(t, err)
assert.Equal(t, float64(0), b.Get())

err = b.UnmarshalJSON([]byte("123.321"))
assert.NoError(t, err)
assert.Equal(t, float64(123.321), b.Get())
}

func TestFloat64_SetString(t *testing.T) {
Expand All @@ -74,6 +120,10 @@ func TestString(t *testing.T) {
<-ch
assert.Equal(t, "Hello", s.Get())
assert.Equal(t, "Hello", s.String())

d, err := s.MarshalJSON()
assert.NoError(t, err)
assert.Equal(t, `"Hello"`, string(d))
}

func TestString_SetString(t *testing.T) {
Expand All @@ -82,6 +132,17 @@ func TestString_SetString(t *testing.T) {
assert.Equal(t, "foo", s.Get())
}

func TestString_UnmarshalJSON(t *testing.T) {
var b String
err := b.UnmarshalJSON([]byte(`foo`))
assert.Error(t, err)
assert.Equal(t, "", b.Get())

err = b.UnmarshalJSON([]byte(`"foo"`))
assert.NoError(t, err)
assert.Equal(t, "foo", b.Get())
}

func TestSecret(t *testing.T) {
var s Secret
ch := make(chan struct{})
Expand All @@ -92,6 +153,10 @@ func TestSecret(t *testing.T) {
<-ch
assert.Equal(t, "Hello", s.Get())
assert.Equal(t, "***", s.String())

d, err := s.MarshalJSON()
assert.NoError(t, err)
assert.Equal(t, `"***"`, string(d))
}

func TestSecret_SetString(t *testing.T) {
Expand All @@ -100,6 +165,13 @@ func TestSecret_SetString(t *testing.T) {
assert.Equal(t, "foo", s.Get())
}

func TestSecret_UnmarshalJSON(t *testing.T) {
var b String
err := b.UnmarshalJSON([]byte(`"foo"`))
assert.NoError(t, err)
assert.Equal(t, "foo", b.Get())
}

func TestTimeDuration(t *testing.T) {
var f TimeDuration
testTime := 3 * time.Second
Expand All @@ -111,6 +183,10 @@ func TestTimeDuration(t *testing.T) {
<-ch
assert.Equal(t, testTime, f.Get())
assert.Equal(t, testTime.String(), f.String())

d, err := f.MarshalJSON()
assert.NoError(t, err)
assert.Equal(t, fmt.Sprintf("%d", testTime.Nanoseconds()), string(d))
}

func TestTimeDuration_SetString(t *testing.T) {
Expand All @@ -120,6 +196,17 @@ func TestTimeDuration_SetString(t *testing.T) {
assert.Equal(t, 3*time.Second, f.Get())
}

func TestTimeDuration_UnmarshalJSON(t *testing.T) {
var b TimeDuration
err := b.UnmarshalJSON([]byte(`foo`))
assert.Error(t, err)
assert.Equal(t, time.Duration(0), b.Get())

err = b.UnmarshalJSON([]byte(`1`))
assert.NoError(t, err)
assert.Equal(t, time.Duration(1), b.Get())
}

func TestStringMap(t *testing.T) {
var sm StringMap
ch := make(chan struct{})
Expand All @@ -130,6 +217,10 @@ func TestStringMap(t *testing.T) {
<-ch
assert.Equal(t, map[string]string{"key": "value"}, sm.Get())
assert.Equal(t, "key=\"value\"", sm.String())

d, err := sm.MarshalJSON()
assert.NoError(t, err)
assert.Equal(t, `{"key":"value"}`, string(d))
}

func TestStringMap_SetString(t *testing.T) {
Expand Down Expand Up @@ -171,3 +262,14 @@ func TestStringMap_SetString_DoesntOverrideValueIfError(t *testing.T) {
assert.Error(t, sm.SetString("k1:v1,k2:v2,k3"))
assert.Equal(t, map[string]string{"k1": "v1"}, sm.Get())
}

func TestStringMap_UnmarshalJSON(t *testing.T) {
var b StringMap
err := b.UnmarshalJSON([]byte(`wrong`))
assert.Error(t, err)
assert.Equal(t, map[string]string(nil), b.Get())

err = b.UnmarshalJSON([]byte(`{ "a": "b" }`))
assert.NoError(t, err)
assert.Equal(t, map[string]string{"a": "b"}, b.Get())
}

0 comments on commit d1bb448

Please sign in to comment.