Skip to content

Commit

Permalink
Merge b48a879 into d895eff
Browse files Browse the repository at this point in the history
  • Loading branch information
peterklijn committed Sep 15, 2022
2 parents d895eff + b48a879 commit cde8aaa
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 2 deletions.
59 changes: 57 additions & 2 deletions sync/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,14 +335,14 @@ func (s *StringMap) MarshalJSON() ([]byte, error) {
return json.Marshal(s.value)
}

// MarshalJSON returns the JSON encoding of the value.
// UnmarshalJSON 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..
// String returns a string representation of the value.
func (s *StringMap) String() string {
s.rw.RLock()
defer s.rw.RUnlock()
Expand Down Expand Up @@ -373,3 +373,58 @@ func (s *StringMap) SetString(val string) error {
s.Set(dict)
return nil
}

// StringSlice is a []string type with concurrent access support.
type StringSlice struct {
rw sync.RWMutex
value []string
}

// Get returns the internal value.
func (s *StringSlice) Get() []string {
s.rw.RLock()
defer s.rw.RUnlock()
return s.value
}

// Set a value.
func (s *StringSlice) Set(value []string) {
s.rw.Lock()
defer s.rw.Unlock()
s.value = value
}

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

// UnmarshalJSON returns the JSON encoding of the value.
func (s *StringSlice) 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 *StringSlice) String() string {
s.rw.RLock()
defer s.rw.RUnlock()
return strings.Join(s.value, ",")
}

// SetString parses and sets a value from string type.
func (s *StringSlice) SetString(val string) error {
slice := make([]string, 0)
if val == "" || strings.TrimSpace(val) == "" {
s.Set(slice)
return nil
}
for _, item := range strings.Split(val, ",") {
slice = append(slice, strings.TrimSpace(item))
}
s.Set(slice)
return nil
}
54 changes: 54 additions & 0 deletions sync/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,3 +273,57 @@ func TestStringMap_UnmarshalJSON(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, map[string]string{"a": "b"}, b.Get())
}

func TestStringSlice(t *testing.T) {
var sl StringSlice
ch := make(chan struct{})
go func() {
sl.Set([]string{"value1", "value2"})
ch <- struct{}{}
}()
<-ch
assert.Equal(t, []string{"value1", "value2"}, sl.Get())
assert.Equal(t, "value1,value2", sl.String())

d, err := sl.MarshalJSON()
assert.NoError(t, err)
assert.Equal(t, `["value1","value2"]`, string(d))
}

func TestStringSlice_SetString(t *testing.T) {
tests := []struct {
name string
input string
result []string
throwsError bool
}{
{"empty", "", []string{}, false},
{"empty with spaces", " ", []string{}, false},
{"single item", "value", []string{"value"}, false},
{"multiple items", "value1,value2", []string{"value1", "value2"}, false},
{"multiple items with spaces", " value1 , value2 ", []string{"value1", "value2"}, false},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
sm := StringSlice{}

err := sm.SetString(test.input)
if test.throwsError {
assert.Error(t, err)
}

assert.Equal(t, test.result, sm.Get())
})
}
}

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

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

0 comments on commit cde8aaa

Please sign in to comment.