member_grouping.gno
2.29 Kb ยท 94 lines
1package commondao
2
3import (
4 "errors"
5
6 "gno.land/p/nt/avl"
7)
8
9// MemberGrouping defines an interface for storing multiple member groups.
10// Member grouping can be used by implementations that require grouping users
11// by roles or by tiers for example.
12type MemberGrouping interface {
13 // Size returns the number of groups that grouping contains.
14 Size() int
15
16 // Has checks if a group exists.
17 Has(name string) bool
18
19 // Add adds an new member group if it doesn't exists.
20 Add(name string) (MemberGroup, error)
21
22 // Get returns a member group.
23 Get(name string) (_ MemberGroup, found bool)
24
25 // Delete deletes a member group.
26 Delete(name string) error
27
28 // IterateByOffset iterates all member groups.
29 IterateByOffset(offset, count int, fn func(MemberGroup) bool)
30}
31
32// NewMemberGrouping creates a new members grouping.
33func NewMemberGrouping(options ...MemberGroupingOption) MemberGrouping {
34 g := &memberGrouping{
35 createStorage: func(string) MemberStorage { return NewMemberStorage() },
36 }
37
38 for _, apply := range options {
39 apply(g)
40 }
41 return g
42}
43
44type memberGrouping struct {
45 groups avl.Tree // string(name) -> MemberGroup
46 createStorage func(group string) MemberStorage
47}
48
49// Size returns the number of groups that grouping contains.
50func (g memberGrouping) Size() int {
51 return g.groups.Size()
52}
53
54// Has checks if a group exists.
55func (g memberGrouping) Has(name string) bool {
56 return g.groups.Has(name)
57}
58
59// Add adds an new member group if it doesn't exists.
60func (g *memberGrouping) Add(name string) (MemberGroup, error) {
61 if g.groups.Has(name) {
62 return nil, errors.New("member group already exists: " + name)
63 }
64
65 mg, err := NewMemberGroup(name, g.createStorage(name))
66 if err != nil {
67 return nil, err
68 }
69
70 g.groups.Set(name, mg)
71 return mg, nil
72}
73
74// Get returns a member group.
75func (g memberGrouping) Get(name string) (_ MemberGroup, found bool) {
76 v, found := g.groups.Get(name)
77 if !found {
78 return nil, false
79 }
80 return v.(MemberGroup), true
81}
82
83// Delete deletes a member group.
84func (g *memberGrouping) Delete(name string) error {
85 g.groups.Remove(name)
86 return nil
87}
88
89// IterateByOffset iterates all member groups.
90func (g memberGrouping) IterateByOffset(offset, count int, fn func(MemberGroup) bool) {
91 g.groups.IterateByOffset(offset, count, func(_ string, v any) bool {
92 return fn(v.(MemberGroup))
93 })
94}