Skip to content

Commit 2951ace

Browse files
committed
broken: Use Member rather than message.User when possible; chat tests are broken.
1 parent 494ac3c commit 2951ace

File tree

7 files changed

+94
-101
lines changed

7 files changed

+94
-101
lines changed

chat/command.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package chat
55
import (
66
"errors"
77
"fmt"
8+
"io"
89
"strings"
910

1011
"github.com/shazow/ssh-chat/chat/message"
@@ -110,7 +111,7 @@ func InitCommands(c *Commands) {
110111
c.Add(Command{
111112
Prefix: "/help",
112113
Handler: func(room *Room, msg message.CommandMsg) error {
113-
op := room.IsOp(msg.From())
114+
op := room.IsOp(msg.From().(Member))
114115
room.Send(message.NewSystemMsg(room.commands.Help(op), msg.From()))
115116
return nil
116117
},
@@ -135,8 +136,7 @@ func InitCommands(c *Commands) {
135136
Prefix: "/exit",
136137
Help: "Exit the chat.",
137138
Handler: func(room *Room, msg message.CommandMsg) error {
138-
msg.From().Close()
139-
return nil
139+
return msg.From().(io.Closer).Close()
140140
},
141141
})
142142
c.Alias("/exit", "/quit")
@@ -150,7 +150,7 @@ func InitCommands(c *Commands) {
150150
if len(args) != 1 {
151151
return ErrMissingArg
152152
}
153-
member, ok := room.MemberByID(msg.From().ID())
153+
member, ok := room.MemberByID(msg.From().(Member).ID())
154154
if !ok {
155155
return ErrMissingMember
156156
}
@@ -184,7 +184,7 @@ func InitCommands(c *Commands) {
184184
PrefixHelp: "[colors|...]",
185185
Help: "Set your color theme. (More themes: solarized, mono, hacker)",
186186
Handler: func(room *Room, msg message.CommandMsg) error {
187-
user := msg.From()
187+
user := msg.From().(Member)
188188
args := msg.Args()
189189
cfg := user.Config()
190190
if len(args) == 0 {
@@ -215,7 +215,7 @@ func InitCommands(c *Commands) {
215215
Prefix: "/quiet",
216216
Help: "Silence room announcements.",
217217
Handler: func(room *Room, msg message.CommandMsg) error {
218-
u := msg.From()
218+
u := msg.From().(Member)
219219
cfg := u.Config()
220220
cfg.Quiet = !cfg.Quiet
221221
u.SetConfig(cfg)
@@ -253,7 +253,7 @@ func InitCommands(c *Commands) {
253253
PrefixHelp: "[USER]",
254254
Help: "Hide messages from USER, /unignore USER to stop hiding.",
255255
Handler: func(room *Room, msg message.CommandMsg) error {
256-
from, ok := room.Member(msg.From())
256+
from, ok := room.Member(msg.From().(Member))
257257
if !ok {
258258
return ErrMissingMember
259259
}
@@ -278,7 +278,7 @@ func InitCommands(c *Commands) {
278278
return nil
279279
}
280280

281-
if id == msg.From().ID() {
281+
if id == msg.From().(Member).ID() {
282282
return errors.New("cannot ignore self")
283283
}
284284
target, ok := room.MemberByID(id)
@@ -302,7 +302,7 @@ func InitCommands(c *Commands) {
302302
Prefix: "/unignore",
303303
PrefixHelp: "USER",
304304
Handler: func(room *Room, msg message.CommandMsg) error {
305-
from, ok := room.Member(msg.From())
305+
from, ok := room.Member(msg.From().(Member))
306306
if !ok {
307307
return ErrMissingMember
308308
}

chat/member.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ type roomMember struct {
1212
}
1313

1414
type Member interface {
15-
ID() string
15+
message.Author
1616

17-
Name() string
17+
ID() string
1818
SetName(string)
1919

2020
Config() message.UserConfig

chat/message/message.go

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import (
66
"time"
77
)
88

9+
type Author interface {
10+
Name() string
11+
Color() int
12+
}
13+
914
// Message is an interface for messages.
1015
type Message interface {
1116
Render(*Theme) string
@@ -16,15 +21,15 @@ type Message interface {
1621

1722
type MessageTo interface {
1823
Message
19-
To() *User
24+
To() Author
2025
}
2126

2227
type MessageFrom interface {
2328
Message
24-
From() *User
29+
From() Author
2530
}
2631

27-
func ParseInput(body string, from *User) Message {
32+
func ParseInput(body string, from Author) Message {
2833
m := NewPublicMsg(body, from)
2934
cmd, isCmd := m.ParseCommand()
3035
if isCmd {
@@ -69,10 +74,10 @@ func (m Msg) Timestamp() time.Time {
6974
// PublicMsg is any message from a user sent to the room.
7075
type PublicMsg struct {
7176
Msg
72-
from *User
77+
from Author
7378
}
7479

75-
func NewPublicMsg(body string, from *User) PublicMsg {
80+
func NewPublicMsg(body string, from Author) PublicMsg {
7681
return PublicMsg{
7782
Msg: Msg{
7883
body: body,
@@ -82,7 +87,7 @@ func NewPublicMsg(body string, from *User) PublicMsg {
8287
}
8388
}
8489

85-
func (m PublicMsg) From() *User {
90+
func (m PublicMsg) From() Author {
8691
return m.from
8792
}
8893

@@ -137,10 +142,10 @@ func (m PublicMsg) String() string {
137142
// sender to see the emote.
138143
type EmoteMsg struct {
139144
Msg
140-
from *User
145+
from Author
141146
}
142147

143-
func NewEmoteMsg(body string, from *User) *EmoteMsg {
148+
func NewEmoteMsg(body string, from Author) *EmoteMsg {
144149
return &EmoteMsg{
145150
Msg: Msg{
146151
body: body,
@@ -161,17 +166,17 @@ func (m EmoteMsg) String() string {
161166
// PrivateMsg is a message sent to another user, not shown to anyone else.
162167
type PrivateMsg struct {
163168
PublicMsg
164-
to *User
169+
to Author
165170
}
166171

167-
func NewPrivateMsg(body string, from *User, to *User) PrivateMsg {
172+
func NewPrivateMsg(body string, from Author, to Author) PrivateMsg {
168173
return PrivateMsg{
169174
PublicMsg: NewPublicMsg(body, from),
170175
to: to,
171176
}
172177
}
173178

174-
func (m PrivateMsg) To() *User {
179+
func (m PrivateMsg) To() Author {
175180
return m.to
176181
}
177182

@@ -191,10 +196,10 @@ func (m PrivateMsg) String() string {
191196
// to anyone else. Usually in response to something, like /help.
192197
type SystemMsg struct {
193198
Msg
194-
to *User
199+
to Author
195200
}
196201

197-
func NewSystemMsg(body string, to *User) *SystemMsg {
202+
func NewSystemMsg(body string, to Author) *SystemMsg {
198203
return &SystemMsg{
199204
Msg: Msg{
200205
body: body,
@@ -215,7 +220,7 @@ func (m *SystemMsg) String() string {
215220
return fmt.Sprintf("-> %s", m.body)
216221
}
217222

218-
func (m *SystemMsg) To() *User {
223+
func (m *SystemMsg) To() Author {
219224
return m.to
220225
}
221226

chat/message/theme.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,12 +127,12 @@ func (t Theme) ID() string {
127127
}
128128

129129
// Colorize name string given some index
130-
func (t Theme) ColorName(u *User) string {
130+
func (t Theme) ColorName(u Author) string {
131131
if t.names == nil {
132132
return u.Name()
133133
}
134134

135-
return t.names.Get(u.colorIdx).Format(u.Name())
135+
return t.names.Get(u.Color()).Format(u.Name())
136136
}
137137

138138
// Colorize the PM string

chat/message/user.go

Lines changed: 57 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,53 @@ const reHighlight = `\b(%s)\b`
1616

1717
var ErrUserClosed = errors.New("user closed")
1818

19-
// User definition, implemented set Item interface and io.Writer
20-
type User struct {
19+
// User container that knows about writing to an IO screen.
20+
type UserScreen struct {
21+
*User
2122
io.WriteCloser
23+
}
24+
25+
func (u *UserScreen) Close() error {
26+
u.User.Close()
27+
return u.WriteCloser.Close()
28+
}
29+
30+
// HandleMsg will render the message to the screen, blocking.
31+
func (u *UserScreen) HandleMsg(m Message) error {
32+
r := u.render(m)
33+
_, err := u.Write([]byte(r))
34+
if err != nil {
35+
logger.Printf("Write failed to %s, closing: %s", u.Name(), err)
36+
u.User.Close()
37+
u.WriteCloser.Close()
38+
}
39+
return err
40+
}
2241

42+
// Consume message buffer into the handler. Will block, should be called in a
43+
// goroutine.
44+
func (u *UserScreen) Consume() {
45+
for {
46+
select {
47+
case <-u.done:
48+
return
49+
case m, ok := <-u.msg:
50+
if !ok {
51+
return
52+
}
53+
u.HandleMsg(m)
54+
}
55+
}
56+
}
57+
58+
// Consume one message and stop, mostly for testing
59+
// TODO: Stop using it and remove it.
60+
func (u *UserScreen) ConsumeOne() Message {
61+
return <-u.msg
62+
}
63+
64+
// User definition, implemented set Item interface and io.Writer
65+
type User struct {
2366
colorIdx int
2467
joined time.Time
2568
closeOnce sync.Once
@@ -29,7 +72,7 @@ type User struct {
2972
mu sync.Mutex
3073
name string
3174
config UserConfig
32-
replyTo *User // Set when user gets a /msg, for replying.
75+
replyTo Author // Set when user gets a /msg, for replying.
3376
}
3477

3578
func NewUser(name string) *User {
@@ -45,11 +88,11 @@ func NewUser(name string) *User {
4588
return &u
4689
}
4790

48-
func NewUserScreen(name string, screen io.WriteCloser) *User {
49-
u := NewUser(name)
50-
u.WriteCloser = screen
51-
52-
return u
91+
func NewUserScreen(name string, screen io.WriteCloser) *UserScreen {
92+
return &UserScreen{
93+
User: NewUser(name),
94+
WriteCloser: screen,
95+
}
5396
}
5497

5598
func (u *User) Config() UserConfig {
@@ -70,6 +113,10 @@ func (u *User) ID() string {
70113
return SanitizeName(u.name)
71114
}
72115

116+
func (u *User) Color() int {
117+
return u.colorIdx
118+
}
119+
73120
func (u *User) Name() string {
74121
u.mu.Lock()
75122
defer u.mu.Unlock()
@@ -89,14 +136,14 @@ func (u *User) SetName(name string) {
89136
}
90137

91138
// ReplyTo returns the last user that messaged this user.
92-
func (u *User) ReplyTo() *User {
139+
func (u *User) ReplyTo() Author {
93140
u.mu.Lock()
94141
defer u.mu.Unlock()
95142
return u.replyTo
96143
}
97144

98145
// SetReplyTo sets the last user to message this user.
99-
func (u *User) SetReplyTo(user *User) {
146+
func (u *User) SetReplyTo(user Author) {
100147
// TODO: Use UserConfig.ReplyTo string
101148
u.mu.Lock()
102149
defer u.mu.Unlock()
@@ -112,46 +159,11 @@ func (u *User) setColorIdx(idx int) {
112159
// Disconnect user, stop accepting messages
113160
func (u *User) Close() {
114161
u.closeOnce.Do(func() {
115-
u.WriteCloser.Close()
116162
// close(u.msg) TODO: Close?
117163
close(u.done)
118164
})
119165
}
120166

121-
// Consume message buffer into the handler. Will block, should be called in a
122-
// goroutine.
123-
func (u *User) Consume() {
124-
for {
125-
select {
126-
case <-u.done:
127-
return
128-
case m, ok := <-u.msg:
129-
if !ok {
130-
return
131-
}
132-
u.HandleMsg(m)
133-
}
134-
}
135-
}
136-
137-
// Consume one message and stop, mostly for testing
138-
// TODO: Stop using it and remove it.
139-
func (u *User) ConsumeOne() Message {
140-
return <-u.msg
141-
}
142-
143-
// Check if there are pending messages, used for testing
144-
// TODO: Stop using it and remove it.
145-
func (u *User) HasMessages() bool {
146-
select {
147-
case msg := <-u.msg:
148-
u.msg <- msg
149-
return true
150-
default:
151-
return false
152-
}
153-
}
154-
155167
// SetHighlight sets the highlighting regular expression to match string.
156168
func (u *User) SetHighlight(s string) error {
157169
re, err := regexp.Compile(fmt.Sprintf(reHighlight, s))
@@ -177,17 +189,6 @@ func (u *User) render(m Message) string {
177189
}
178190
}
179191

180-
// HandleMsg will render the message to the screen, blocking.
181-
func (u *User) HandleMsg(m Message) error {
182-
r := u.render(m)
183-
_, err := u.Write([]byte(r))
184-
if err != nil {
185-
logger.Printf("Write failed to %s, closing: %s", u.Name(), err)
186-
u.Close()
187-
}
188-
return err
189-
}
190-
191192
// Add message to consume by user
192193
func (u *User) Send(m Message) error {
193194
select {

0 commit comments

Comments
 (0)