From 1377dbc42dd50992733d586b639c6929fe5f4f58 Mon Sep 17 00:00:00 2001 From: joshjennings98 Date: Tue, 27 Aug 2024 11:20:03 +0100 Subject: [PATCH 1/4] :sparkles: Add support for parsing a comma separated string list as a map of key-value pairs --- changes/20240827111953.feature | 1 + utils/collection/parseLists.go | 22 +++++++++++++++++ utils/collection/parseLists_test.go | 37 +++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 changes/20240827111953.feature diff --git a/changes/20240827111953.feature b/changes/20240827111953.feature new file mode 100644 index 0000000000..4b9a6c1d55 --- /dev/null +++ b/changes/20240827111953.feature @@ -0,0 +1 @@ +:sparkles: Add support for parsing a comma separated string list as a map of key-value pairs diff --git a/utils/collection/parseLists.go b/utils/collection/parseLists.go index 2e72395490..401a08fa03 100644 --- a/utils/collection/parseLists.go +++ b/utils/collection/parseLists.go @@ -5,8 +5,11 @@ package collection import ( + "fmt" "strings" "unicode" + + "github.com/ARM-software/golang-utils/utils/commonerrors" ) func lineIsOnlyWhitespace(line string) bool { @@ -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) + + for i := 0; i < numElements; i += 2 { + pairs[inputSplit[i]] = inputSplit[i+1] + } + + return +} diff --git a/utils/collection/parseLists_test.go b/utils/collection/parseLists_test.go index 1a497f271e..e24b2ca0a1 100644 --- a/utils/collection/parseLists_test.go +++ b/utils/collection/parseLists_test.go @@ -9,8 +9,12 @@ import ( "testing" "time" + "github.com/ARM-software/golang-utils/utils/commonerrors" + "github.com/ARM-software/golang-utils/utils/commonerrors/errortest" "github.com/go-faker/faker/v4" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "golang.org/x/exp/maps" ) var ( @@ -87,3 +91,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)) + }) + } +} From 95e49c60d4ef321234aeee3dac1721912bdd5f47 Mon Sep 17 00:00:00 2001 From: joshjennings98 Date: Tue, 27 Aug 2024 11:48:31 +0100 Subject: [PATCH 2/4] imports lint --- utils/collection/parseLists_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/utils/collection/parseLists_test.go b/utils/collection/parseLists_test.go index e24b2ca0a1..6af5d22c0a 100644 --- a/utils/collection/parseLists_test.go +++ b/utils/collection/parseLists_test.go @@ -9,12 +9,13 @@ import ( "testing" "time" - "github.com/ARM-software/golang-utils/utils/commonerrors" - "github.com/ARM-software/golang-utils/utils/commonerrors/errortest" "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 ( From 3c01648a6e3bc977a3cd5f7c31c662d44c16a7bd Mon Sep 17 00:00:00 2001 From: Josh Date: Tue, 27 Aug 2024 13:19:19 +0100 Subject: [PATCH 3/4] Update utils/collection/parseLists.go Co-authored-by: Adrien CABARBAYE --- utils/collection/parseLists.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/collection/parseLists.go b/utils/collection/parseLists.go index 401a08fa03..c726980483 100644 --- a/utils/collection/parseLists.go +++ b/utils/collection/parseLists.go @@ -67,7 +67,7 @@ func ParseCommaSeparatedListToMap(input string) (pairs map[string]string, err er } 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] } From f5e0c1da49d3a2ec737d632767e3bd83997defa0 Mon Sep 17 00:00:00 2001 From: joshjennings98 Date: Tue, 27 Aug 2024 13:43:21 +0100 Subject: [PATCH 4/4] fmt --- utils/collection/parseLists.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/collection/parseLists.go b/utils/collection/parseLists.go index c726980483..d2e2f95b1d 100644 --- a/utils/collection/parseLists.go +++ b/utils/collection/parseLists.go @@ -67,7 +67,7 @@ func ParseCommaSeparatedListToMap(input string) (pairs map[string]string, err er } pairs = make(map[string]string, numElements/2) -// TODO use slices.Chunk introduced in go 23 when library is upgraded + // 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] }