summaryrefslogtreecommitdiffstats
path: root/modules/container
diff options
context:
space:
mode:
authorKN4CK3R <admin@oldschoolhack.me>2022-10-12 07:18:26 +0200
committerGitHub <noreply@github.com>2022-10-12 13:18:26 +0800
commit0e57ff7eee4ac71d923f970d15889ad4d50f97a9 (patch)
treee5a92c55af5366924bd40ae14b4bf12842239193 /modules/container
parente84558b0931309cf1f4f2767bc47296483b9b3e1 (diff)
downloadgitea-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.go14
-rw-r--r--modules/container/set.go57
-rw-r--r--modules/container/set_test.go37
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"))
+}