member_grouping.gno

2.08 Kb ยท 86 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() MemberGrouping {
34	return &memberGrouping{}
35}
36
37type memberGrouping struct {
38	groups avl.Tree // string(name) -> MemberGroup
39}
40
41// Size returns the number of groups that grouping contains.
42func (g memberGrouping) Size() int {
43	return g.groups.Size()
44}
45
46// Has checks if a group exists.
47func (g memberGrouping) Has(name string) bool {
48	return g.groups.Has(name)
49}
50
51// Add adds an new member group if it doesn't exists.
52func (g *memberGrouping) Add(name string) (MemberGroup, error) {
53	if g.groups.Has(name) {
54		return nil, errors.New("member group already exists: " + name)
55	}
56
57	mg, err := NewMemberGroup(name, NewMemberStorage())
58	if err != nil {
59		return nil, err
60	}
61
62	g.groups.Set(name, mg)
63	return mg, nil
64}
65
66// Get returns a member group.
67func (g memberGrouping) Get(name string) (_ MemberGroup, found bool) {
68	v, found := g.groups.Get(name)
69	if !found {
70		return nil, false
71	}
72	return v.(MemberGroup), true
73}
74
75// Delete deletes a member group.
76func (g *memberGrouping) Delete(name string) error {
77	g.groups.Remove(name)
78	return nil
79}
80
81// IterateByOffset iterates all member groups.
82func (g memberGrouping) IterateByOffset(offset, count int, fn func(MemberGroup) bool) {
83	g.groups.IterateByOffset(offset, count, func(_ string, v any) bool {
84		return fn(v.(MemberGroup))
85	})
86}