diff --git a/util/nocasemaps/nocase.go b/util/nocasemaps/nocase.go index eaaaef559..4da7e6c9b 100644 --- a/util/nocasemaps/nocase.go +++ b/util/nocasemaps/nocase.go @@ -74,6 +74,22 @@ func Delete[K ~string, V any](m map[K]V, k K) { delete(m, K(appendToLower(a[:0], string(k)))) } +// AppendSliceElem is equivalent to: +// +// append(m[strings.ToLower(k)], v) +func AppendSliceElem[K ~string, S []E, E any](m map[K]S, k K, vs ...E) { + // if the key is already lowercased + if isLowerASCII(string(k)) { + m[k] = append(m[k], vs...) + return + } + + // if key needs to become lowercase, uses appendToLower + var a [stackArraySize]byte + s := appendToLower(a[:0], string(k)) + m[K(s)] = append(m[K(s)], vs...) +} + func isLowerASCII(s string) bool { for i := 0; i < len(s); i++ { if c := s[i]; c >= utf8.RuneSelf || ('A' <= c && c <= 'Z') { diff --git a/util/nocasemaps/nocase_test.go b/util/nocasemaps/nocase_test.go index 310f82889..7d99f38ff 100644 --- a/util/nocasemaps/nocase_test.go +++ b/util/nocasemaps/nocase_test.go @@ -45,6 +45,23 @@ func Test(t *testing.T) { c.Assert(m, qt.DeepEquals, map[string]int{"hello": 2, "baz": 5}) Delete(m, "BAZ") c.Assert(m, qt.DeepEquals, map[string]int{"hello": 2}) + // test cases for AppendSliceElem with int slices + appendTestInt := make(map[string][]int) + Set(appendTestInt, "firsT", []int{7}) + c.Assert(appendTestInt, qt.DeepEquals, map[string][]int{"first": {7}}) + AppendSliceElem(appendTestInt, "firsT", 77) + c.Assert(appendTestInt, qt.DeepEquals, map[string][]int{"first": {7, 77}}) + Set(appendTestInt, "SeCOnd", []int{56}) + c.Assert(appendTestInt, qt.DeepEquals, map[string][]int{"first": {7, 77}, "second": {56}}) + AppendSliceElem(appendTestInt, "seCOnd", 563, 23) + c.Assert(appendTestInt, qt.DeepEquals, map[string][]int{"first": {7, 77}, "second": {56, 563, 23}}) + // test cases for AppendSliceElem with string slices + appendTestString := make(map[string][]string) + Set(appendTestString, "firsTSTRING", []string{"hi"}) + c.Assert(appendTestString, qt.DeepEquals, map[string][]string{"firststring": {"hi"}}) + AppendSliceElem(appendTestString, "firsTSTRING", "hello", "bye") + c.Assert(appendTestString, qt.DeepEquals, map[string][]string{"firststring": {"hi", "hello", "bye"}}) + } var lowerTests = []struct{ in, want string }{