Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 changes/20240827111953.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:sparkles: Add support for parsing a comma separated string list as a map of key-value pairs
22 changes: 22 additions & 0 deletions utils/collection/parseLists.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
package collection

import (
"fmt"
"strings"
"unicode"

"github.com/ARM-software/golang-utils/utils/commonerrors"
)

func lineIsOnlyWhitespace(line string) bool {
Expand Down Expand Up @@ -52,3 +55,22 @@ func ParseListWithCleanupKeepBlankLines(input string, sep string) (newS []string
func ParseCommaSeparatedList(input string) []string {
return ParseListWithCleanup(input, ",")
}

// ParseCommaSeparatedListToMap returns a map of key value pairs from a string containing a comma separated list
func ParseCommaSeparatedListToMap(input string) (pairs map[string]string, err error) {
inputSplit := ParseCommaSeparatedList(input)
numElements := len(inputSplit)

if numElements%2 != 0 {
err = fmt.Errorf("%w: could not parse comma separated list '%v' into map as it did not have an even number of elements", commonerrors.ErrInvalid, input)
return
}

pairs = make(map[string]string, numElements/2)
// TODO use slices.Chunk introduced in go 23 when library is upgraded
for i := 0; i < numElements; i += 2 {
pairs[inputSplit[i]] = inputSplit[i+1]
}

return
}
38 changes: 38 additions & 0 deletions utils/collection/parseLists_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ import (
"time"

"github.com/go-faker/faker/v4"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/exp/maps"

"github.com/ARM-software/golang-utils/utils/commonerrors"
"github.com/ARM-software/golang-utils/utils/commonerrors/errortest"
)

var (
Expand Down Expand Up @@ -87,3 +92,36 @@ func TestParseCommaSeparatedListWithSpacesBetweenWordsKeepBlanks(t *testing.T) {
finalList2 := ParseListWithCleanupKeepBlankLines(stringList, ",")
require.Equal(t, stringArray, finalList2)
}

func TestParseCommaSeparatedListToMap(t *testing.T) {
for _, test := range []struct {
Name string
Input string
Expected map[string]string
Err error
}{
{"Normal 1", "hello,world", map[string]string{"hello": "world"}, nil},
{"Normal 2", "hello,world,adrien,cabarbaye", map[string]string{"hello": "world", "adrien": "cabarbaye"}, nil},
{"Normal 2.5", "hello, world, adrien, cabarbaye", map[string]string{"hello": "world", "adrien": "cabarbaye"}, nil},
{"Normal 3", "hello,world,adrien,cabarbaye,", map[string]string{"hello": "world", "adrien": "cabarbaye"}, nil},
{"Normal 4", "hello,,world,adrien,,,cabarbaye,,,", map[string]string{"hello": "world", "adrien": "cabarbaye"}, nil},
{"Normal 5", "hello,world,this,value has spaces", map[string]string{"hello": "world", "this": "value has spaces"}, nil},
{"Normal 6", "hello,,world,this,,,value has spaces,,,", map[string]string{"hello": "world", "this": "value has spaces"}, nil},
{"Normal 7", "", map[string]string{}, nil},
{"Normal 8", ",", map[string]string{}, nil},
{"Normal 9", ",,,,,", map[string]string{}, nil},
{"Normal 10", ",, ,, ,", map[string]string{}, nil},
{"Bad 1", "one", nil, commonerrors.ErrInvalid},
{"Bad 1", "one, two, three", nil, commonerrors.ErrInvalid},
{"Bad 2", "one element with spaces", nil, commonerrors.ErrInvalid},
{"Bad 3", "one element with spaces and end comma,", nil, commonerrors.ErrInvalid},
{"Bad 4", "one element with spaces and multiple end commas,,,", nil, commonerrors.ErrInvalid},
{"Bad 5", ",,,one element with spaces and multiple end/beginning commas,,,", nil, commonerrors.ErrInvalid},
} {
t.Run(test.Name, func(t *testing.T) {
pairs, err := ParseCommaSeparatedListToMap(test.Input)
errortest.AssertError(t, err, test.Err)
assert.True(t, maps.Equal(test.Expected, pairs))
})
}
}