diff options
author | KN4CK3R <admin@oldschoolhack.me> | 2022-10-12 07:18:26 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-12 13:18:26 +0800 |
commit | 0e57ff7eee4ac71d923f970d15889ad4d50f97a9 (patch) | |
tree | e5a92c55af5366924bd40ae14b4bf12842239193 /modules/container | |
parent | e84558b0931309cf1f4f2767bc47296483b9b3e1 (diff) | |
download | gitea-0e57ff7eee4ac71d923f970d15889ad4d50f97a9.tar.gz gitea-0e57ff7eee4ac71d923f970d15889ad4d50f97a9.zip |
Add generic set type (#21408)
This PR adds a generic set type to get rid of maps used as sets.
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Diffstat (limited to 'modules/container')
-rw-r--r-- | modules/container/map.go | 14 | ||||
-rw-r--r-- | modules/container/set.go | 57 | ||||
-rw-r--r-- | modules/container/set_test.go | 37 |
3 files changed, 94 insertions, 14 deletions
diff --git a/modules/container/map.go b/modules/container/map.go deleted file mode 100644 index 3519de0951..0000000000 --- a/modules/container/map.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2022 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package container - -// KeysInt64 returns keys slice for a map with int64 key -func KeysInt64(m map[int64]struct{}) []int64 { - keys := make([]int64, 0, len(m)) - for k := range m { - keys = append(keys, k) - } - return keys -} diff --git a/modules/container/set.go b/modules/container/set.go new file mode 100644 index 0000000000..4b4c74525d --- /dev/null +++ b/modules/container/set.go @@ -0,0 +1,57 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package container + +type Set[T comparable] map[T]struct{} + +// SetOf creates a set and adds the specified elements to it. +func SetOf[T comparable](values ...T) Set[T] { + s := make(Set[T], len(values)) + s.AddMultiple(values...) + return s +} + +// Add adds the specified element to a set. +// Returns true if the element is added; false if the element is already present. +func (s Set[T]) Add(value T) bool { + if _, has := s[value]; !has { + s[value] = struct{}{} + return true + } + return false +} + +// AddMultiple adds the specified elements to a set. +func (s Set[T]) AddMultiple(values ...T) { + for _, value := range values { + s.Add(value) + } +} + +// Contains determines whether a set contains the specified element. +// Returns true if the set contains the specified element; otherwise, false. +func (s Set[T]) Contains(value T) bool { + _, has := s[value] + return has +} + +// Remove removes the specified element. +// Returns true if the element is successfully found and removed; otherwise, false. +func (s Set[T]) Remove(value T) bool { + if _, has := s[value]; has { + delete(s, value) + return true + } + return false +} + +// Values gets a list of all elements in the set. +func (s Set[T]) Values() []T { + keys := make([]T, 0, len(s)) + for k := range s { + keys = append(keys, k) + } + return keys +} diff --git a/modules/container/set_test.go b/modules/container/set_test.go new file mode 100644 index 0000000000..6654763e56 --- /dev/null +++ b/modules/container/set_test.go @@ -0,0 +1,37 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package container + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestSet(t *testing.T) { + s := make(Set[string]) + + assert.True(t, s.Add("key1")) + assert.False(t, s.Add("key1")) + assert.True(t, s.Add("key2")) + + assert.True(t, s.Contains("key1")) + assert.True(t, s.Contains("key2")) + assert.False(t, s.Contains("key3")) + + assert.True(t, s.Remove("key2")) + assert.False(t, s.Contains("key2")) + + assert.False(t, s.Remove("key3")) + + s.AddMultiple("key4", "key5") + assert.True(t, s.Contains("key4")) + assert.True(t, s.Contains("key5")) + + s = SetOf("key6", "key7") + assert.False(t, s.Contains("key1")) + assert.True(t, s.Contains("key6")) + assert.True(t, s.Contains("key7")) +} |