diff --git a/android/util.go b/android/util.go index 3c0af2f38..2d269b724 100644 --- a/android/util.go +++ b/android/util.go @@ -177,6 +177,41 @@ func setFromList[T comparable](l []T) map[T]bool { return m } +// PrettyConcat returns the formatted concatenated string suitable for displaying user-facing +// messages. +func PrettyConcat(list []string, quote bool, lastSep string) string { + if len(list) == 0 { + return "" + } + + quoteStr := func(v string) string { + if !quote { + return v + } + return fmt.Sprintf("%q", v) + } + + if len(list) == 1 { + return quoteStr(list[0]) + } + + var sb strings.Builder + for i, val := range list { + if i > 0 { + sb.WriteString(", ") + } + if i == len(list)-1 { + sb.WriteString(lastSep) + if lastSep != "" { + sb.WriteString(" ") + } + } + sb.WriteString(quoteStr(val)) + } + + return sb.String() +} + // ListSetDifference checks if the two lists contain the same elements. It returns // a boolean which is true if there is a difference, and then returns lists of elements // that are in l1 but not l2, and l2 but not l1. diff --git a/android/util_test.go b/android/util_test.go index 6537d69b9..b76ffcfea 100644 --- a/android/util_test.go +++ b/android/util_test.go @@ -867,3 +867,51 @@ func TestHasIntersection(t *testing.T) { }) } } + +var prettyConcatTestCases = []struct { + name string + list []string + quote bool + lastSeparator string + expected string +}{ + { + name: "empty", + list: []string{}, + quote: false, + lastSeparator: "and", + expected: ``, + }, + { + name: "single", + list: []string{"a"}, + quote: true, + lastSeparator: "and", + expected: `"a"`, + }, + { + name: "with separator", + list: []string{"a", "b", "c"}, + quote: true, + lastSeparator: "or", + expected: `"a", "b", or "c"`, + }, + { + name: "without separator", + list: []string{"a", "b", "c"}, + quote: false, + lastSeparator: "", + expected: `a, b, c`, + }, +} + +func TestPrettyConcat(t *testing.T) { + for _, testCase := range prettyConcatTestCases { + t.Run(testCase.name, func(t *testing.T) { + concatString := PrettyConcat(testCase.list, testCase.quote, testCase.lastSeparator) + if !reflect.DeepEqual(concatString, testCase.expected) { + t.Errorf("expected %#v, got %#v", testCase.expected, concatString) + } + }) + } +}