]> git.r.bdr.sh - rbdr/mobius/blame - hotline/chat.go
Fix failing test, replace use of reflect package with assert
[rbdr/mobius] / hotline / chat.go
CommitLineData
d9bc63a1
JH
1package hotline
2
3import (
4 "crypto/rand"
5 "github.com/stretchr/testify/mock"
6 "slices"
7 "sync"
8)
9
10type PrivateChat struct {
11 Subject string
12 ClientConn map[[2]byte]*ClientConn
13}
14
15type ChatID [4]byte
16
17type ChatManager interface {
18 New(cc *ClientConn) ChatID
19 GetSubject(id ChatID) string
20 Join(id ChatID, cc *ClientConn)
21 Leave(id ChatID, clientID [2]byte)
22 SetSubject(id ChatID, subject string)
23 Members(id ChatID) []*ClientConn
24}
25
d9bc63a1
JH
26type MemChatManager struct {
27 chats map[ChatID]*PrivateChat
28
29 mu sync.Mutex
30}
31
32func NewMemChatManager() *MemChatManager {
33 return &MemChatManager{
34 chats: make(map[ChatID]*PrivateChat),
35 }
36}
37
38func (cm *MemChatManager) New(cc *ClientConn) ChatID {
39 cm.mu.Lock()
40 defer cm.mu.Unlock()
41
42 var randID [4]byte
43 _, _ = rand.Read(randID[:])
44
45 cm.chats[randID] = &PrivateChat{ClientConn: make(map[[2]byte]*ClientConn)}
46
47 cm.chats[randID].ClientConn[cc.ID] = cc
48
49 return randID
50}
51
52func (cm *MemChatManager) Join(id ChatID, cc *ClientConn) {
53 cm.mu.Lock()
54 defer cm.mu.Unlock()
55
56 chat := cm.chats[id]
57 chat.ClientConn[cc.ID] = cc
58}
59
60func (cm *MemChatManager) Leave(id ChatID, clientID [2]byte) {
61 cm.mu.Lock()
62 defer cm.mu.Unlock()
63
64 privChat, ok := cm.chats[id]
65 if !ok {
66 return
67 }
68
69 delete(privChat.ClientConn, clientID)
70}
71
72func (cm *MemChatManager) GetSubject(id ChatID) string {
73 cm.mu.Lock()
74 defer cm.mu.Unlock()
75
76 return cm.chats[id].Subject
77}
78
79func (cm *MemChatManager) Members(id ChatID) []*ClientConn {
80 cm.mu.Lock()
81 defer cm.mu.Unlock()
82
83 chat := cm.chats[id]
84
85 var members []*ClientConn
86 for _, cc := range chat.ClientConn {
87 members = append(members, cc)
88 }
89
90 slices.SortFunc(members, clientConnSortFunc)
91
92 return members
93}
94
95func (cm *MemChatManager) SetSubject(id ChatID, subject string) {
96 cm.mu.Lock()
97 defer cm.mu.Unlock()
98
99 chat := cm.chats[id]
100
101 chat.Subject = subject
102}
fd740bc4
JH
103
104type MockChatManager struct {
105 mock.Mock
106}
107
108func (m *MockChatManager) New(cc *ClientConn) ChatID {
109 args := m.Called(cc)
110
111 return args.Get(0).(ChatID)
112}
113
114func (m *MockChatManager) GetSubject(id ChatID) string {
115 args := m.Called(id)
116
117 return args.String(0)
118}
119
120func (m *MockChatManager) Join(id ChatID, cc *ClientConn) {
121 m.Called(id, cc)
122}
123
124func (m *MockChatManager) Leave(id ChatID, clientID [2]byte) {
125 m.Called(id, clientID)
126}
127
128func (m *MockChatManager) SetSubject(id ChatID, subject string) {
129 m.Called(id, subject)
130
131}
132
133func (m *MockChatManager) Members(id ChatID) []*ClientConn {
134 args := m.Called(id)
135
136 return args.Get(0).([]*ClientConn)
137}