diff --git a/src/irc/commands.go b/src/irc/commands.go index 2a222a1a..5c848d1e 100644 --- a/src/irc/commands.go +++ b/src/irc/commands.go @@ -1,27 +1,13 @@ package irc -import ( - "strconv" - "strings" -) - type Message interface { Handle(s *Server, c *Client) } -type NewMessageFunc func([]string) Message - type NickMessage struct { nickname string } -func NewNickMessage(args []string) Message { - if len(args) != 1 { - return nil - } - return &NickMessage{args[0]} -} - func (m *NickMessage) Handle(s *Server, c *Client) { if s.nicks[m.nickname] != nil { c.send <- ErrNickNameInUse(m.nickname) @@ -42,21 +28,6 @@ type UserMessage struct { realname string } -func NewUserMessage(args []string) Message { - if len(args) != 4 { - return nil - } - msg := new(UserMessage) - msg.user = args[0] - mode, err := strconv.ParseUint(args[1], 10, 8) - if err == nil { - msg.mode = uint8(mode) - } - msg.unused = args[2] - msg.realname = args[3] - return msg -} - func (m *UserMessage) Handle(s *Server, c *Client) { if c.username != "" { c.send <- ErrAlreadyRegistered(c.Nick()) @@ -70,14 +41,6 @@ type QuitMessage struct { message string } -func NewQuitMessage(args []string) Message { - msg := QuitMessage{} - if len(args) > 0 { - msg.message = args[0] - } - return &msg -} - func (m *QuitMessage) Handle(s *Server, c *Client) { c.send <- MessageError() delete(s.nicks, c.nick) @@ -93,10 +56,6 @@ func (m *UnknownMessage) Handle(s *Server, c *Client) { type PingMessage struct {} -func NewPingMessage(args []string) Message { - return &PingMessage{} -} - func (m *PingMessage) Handle(s *Server, c *Client) { c.send <- MessagePong() } @@ -110,49 +69,3 @@ func tryRegister(s *Server, c *Client) { c.send <- ReplyMyInfo(c.Nick(), "irc.jlatt.com") } } - -func parseArg(line string) (string, string) { - if line == "" { - return "", "" - } - - if strings.HasPrefix(line, ":") { - return line[1:], "" - } - - parts := strings.SplitN(line, " ", 2) - arg := parts[0] - rest := "" - if len(parts) > 1 { - rest = parts[1] - } - return arg, rest -} - -func parseLine(line string) (string, []string) { - args := make([]string, 0) - for arg, rest := parseArg(line); arg != ""; arg, rest = parseArg(rest) { - args = append(args, arg) - } - return args[0], args[1:] -} - -var commands = map[string]NewMessageFunc { - "NICK": NewNickMessage, - "PING": NewPingMessage, - "QUIT": NewQuitMessage, - "USER": NewUserMessage, -} - -func ParseMessage(line string) Message { - command, args := parseLine(line) - constructor := commands[command] - var msg Message - if constructor != nil { - msg = constructor(args) - } - if msg == nil { - msg = &UnknownMessage{command} - } - return msg -} diff --git a/src/irc/parse.go b/src/irc/parse.go new file mode 100644 index 00000000..1ceea9b0 --- /dev/null +++ b/src/irc/parse.go @@ -0,0 +1,88 @@ +package irc + +import ( + "strconv" + "strings" +) + +func parseArg(line string) (string, string) { + if line == "" { + return "", "" + } + + if strings.HasPrefix(line, ":") { + return line[1:], "" + } + + parts := strings.SplitN(line, " ", 2) + arg := parts[0] + rest := "" + if len(parts) > 1 { + rest = parts[1] + } + return arg, rest +} + +func parseLine(line string) (string, []string) { + args := make([]string, 0) + for arg, rest := parseArg(line); arg != ""; arg, rest = parseArg(rest) { + args = append(args, arg) + } + return args[0], args[1:] +} + +var commands = map[string]func([]string) Message { + "NICK": NewNickMessage, + "PING": NewPingMessage, + "QUIT": NewQuitMessage, + "USER": NewUserMessage, +} + +func ParseMessage(line string) Message { + command, args := parseLine(line) + constructor, ok := commands[command] + var msg Message + if ok { + msg = constructor(args) + } + if msg == nil { + msg = &UnknownMessage{command} + } + return msg +} + +// []string => Message constructors + +func NewNickMessage(args []string) Message { + if len(args) != 1 { + return nil + } + return &NickMessage{args[0]} +} + +func NewPingMessage(args []string) Message { + return &PingMessage{} +} + +func NewQuitMessage(args []string) Message { + msg := QuitMessage{} + if len(args) > 0 { + msg.message = args[0] + } + return &msg +} + +func NewUserMessage(args []string) Message { + if len(args) != 4 { + return nil + } + msg := new(UserMessage) + msg.user = args[0] + mode, err := strconv.ParseUint(args[1], 10, 8) + if err == nil { + msg.mode = uint8(mode) + } + msg.unused = args[2] + msg.realname = args[3] + return msg +}