package irc import ( "errors" "fmt" "regexp" "strings" ) type ircMessage struct { from *ircClient //received tags string source string raw string command string params []string } func parseIrcLine(line string) (*ircMessage, error) { //FIXME do this at compile or start time instead of every message ircregex, err := regexp.Compile(`^(\@(\S+) )?(?:[:](\S+) )?(\S+)(?: ([^:].+?))?(?: [:](.+))?$`) if err != nil { panic("can't happen") } line = strings.TrimRight(line, "\r\n") m := new(ircMessage) m.raw = line if ircregex.MatchString(m.raw) == false { return nil, errors.New("parse error") } matches := ircregex.FindAllStringSubmatch(m.raw, -1) if len(matches) == 0 { return nil, errors.New("parse error") } match := matches[0] fmt.Printf("%+v\n", match) fmt.Printf("%+v\n", len(match)) m.tags = match[2] m.source = match[3] m.command = strings.ToUpper(match[4]) if len(match[5]) > 0 { m.params = strings.Fields(match[5]) } if len(match[6]) > 0 { m.params = append(m.params, match[6]) } return m, nil } func NewIrcMessageFromString(line string, from *ircClient) *ircMessage { msg, err := parseIrcLine(line) msg.from = from if err != nil { panic("wat") } return msg } func (m *ircMessage) String() string { return fmt.Sprintf("IRCMessage<%s>('%s')", m.command, strings.Join(m.params, ",")) }