#![allow(dead_code)] use std::fmt::{FormatError, Formatter, Show}; use std::from_str::FromStr; #[deriving(PartialEq, Eq)] pub enum MessageType { Pass, Nick, User, Server, Oper, Quit, Squit, Join, Part, Mode, Topic, Names, List, Invite, Kick, Version, Stats, Links, Time, Connect, Trace, Admin, Info, Privmsg, Notice, Who, Whois, Whowas, Kill, Ping, Pong, Error, Away, Rehash, Restart, Summon, Users, Wallops, Userhost, Ison, RawCommand(String), Reply(u16), } impl Show for MessageType { fn fmt (&self, f: &mut Formatter) -> Result<(), FormatError> { match self { &Pass => try!(write!(f, "PASS")), &Nick => try!(write!(f, "NICK")), &User => try!(write!(f, "USER")), &Server => try!(write!(f, "SERVER")), &Oper => try!(write!(f, "OPER")), &Quit => try!(write!(f, "QUIT")), &Squit => try!(write!(f, "SQUIT")), &Join => try!(write!(f, "JOIN")), &Part => try!(write!(f, "PART")), &Mode => try!(write!(f, "MODE")), &Topic => try!(write!(f, "TOPIC")), &Names => try!(write!(f, "NAMES")), &List => try!(write!(f, "LIST")), &Invite => try!(write!(f, "INVITE")), &Kick => try!(write!(f, "KICK")), &Version => try!(write!(f, "VERSION")), &Stats => try!(write!(f, "STATS")), &Links => try!(write!(f, "LINKS")), &Time => try!(write!(f, "TIME")), &Connect => try!(write!(f, "CONNECT")), &Trace => try!(write!(f, "TRACE")), &Admin => try!(write!(f, "ADMIN")), &Info => try!(write!(f, "INFO")), &Privmsg => try!(write!(f, "PRIVMSG")), &Notice => try!(write!(f, "NOTICE")), &Who => try!(write!(f, "WHO")), &Whois => try!(write!(f, "WHOIS")), &Whowas => try!(write!(f, "WHOWAS")), &Kill => try!(write!(f, "KILL")), &Ping => try!(write!(f, "PING")), &Pong => try!(write!(f, "PONG")), &Error => try!(write!(f, "ERROR")), &Away => try!(write!(f, "AWAY")), &Rehash => try!(write!(f, "REHASH")), &Restart => try!(write!(f, "RESTART")), &Summon => try!(write!(f, "SUMMON")), &Users => try!(write!(f, "USERS")), &Wallops => try!(write!(f, "WALLOPS")), &Userhost => try!(write!(f, "USERHOST")), &Ison => try!(write!(f, "ISON")), &RawCommand(ref s) => try!(write!(f, "{}", s)), &Reply(i) => try!(write!(f, "{:03}", i)), } Ok(()) } } impl FromStr for MessageType { fn from_str (s: &str) -> Option { match s { "PASS" => Some(Pass), "NICK" => Some(Nick), "USER" => Some(User), "SERVER" => Some(Server), "OPER" => Some(Oper), "QUIT" => Some(Quit), "SQUIT" => Some(Squit), "JOIN" => Some(Join), "PART" => Some(Part), "MODE" => Some(Mode), "TOPIC" => Some(Topic), "NAMES" => Some(Names), "LIST" => Some(List), "INVITE" => Some(Invite), "KICK" => Some(Kick), "VERSION" => Some(Version), "STATS" => Some(Stats), "LINKS" => Some(Links), "TIME" => Some(Time), "CONNECT" => Some(Connect), "TRACE" => Some(Trace), "ADMIN" => Some(Admin), "INFO" => Some(Info), "PRIVMSG" => Some(Privmsg), "NOTICE" => Some(Notice), "WHO" => Some(Who), "WHOIS" => Some(Whois), "WHOWAS" => Some(Whowas), "KILL" => Some(Kill), "PING" => Some(Ping), "PONG" => Some(Pong), "ERROR" => Some(Error), "AWAY" => Some(Away), "REHASH" => Some(Rehash), "RESTART" => Some(Restart), "SUMMON" => Some(Summon), "USERS" => Some(Users), "WALLOPS" => Some(Wallops), "USERHOST" => Some(Userhost), "ISON" => Some(Ison), s => { match s.char_at(0) { '0'..'9' => { match from_str(s) { Some(i) => Some(Reply(i)), None => Some(RawCommand(s.to_string())), } }, _ => Some(RawCommand(s.to_string())), } }, } } } impl MessageType { pub fn is_reply (&self) -> bool { match self { &Reply(_) => true, _ => false, } } } // normal replies pub static RPL_WELCOME: u16 = 1; pub static RPL_YOURHOST: u16 = 2; pub static RPL_CREATED: u16 = 3; pub static RPL_MYINFO: u16 = 4; pub static RPL_BOUNCE: u16 = 5; pub static RPL_USERHOST: u16 = 302; pub static RPL_ISON: u16 = 303; pub static RPL_AWAY: u16 = 301; pub static RPL_UNAWAY: u16 = 305; pub static RPL_NOWAWAY: u16 = 306; pub static RPL_WHOISUSER: u16 = 311; pub static RPL_WHOISSERVER: u16 = 312; pub static RPL_WHOISOPERATOR: u16 = 313; pub static RPL_WHOISIDLE: u16 = 317; pub static RPL_ENDOFWHOIS: u16 = 318; pub static RPL_WHOISCHANNELS: u16 = 319; pub static RPL_WHOWASUSER: u16 = 314; pub static RPL_ENDOFWHOWAS: u16 = 369; pub static RPL_LISTSTART: u16 = 321; pub static RPL_LIST: u16 = 322; pub static RPL_LISTEND: u16 = 323; pub static RPL_UNIQOPIS: u16 = 325; pub static RPL_CHANNELMODEIS: u16 = 324; pub static RPL_NOTOPIC: u16 = 331; pub static RPL_TOPIC: u16 = 332; pub static RPL_INVITING: u16 = 341; pub static RPL_SUMMONING: u16 = 342; pub static RPL_INVITELIST: u16 = 346; pub static RPL_ENDOFINVITELIST: u16 = 347; pub static RPL_EXCEPTLIST: u16 = 348; pub static RPL_ENDOFEXCEPTLIST: u16 = 349; pub static RPL_VERSION: u16 = 351; pub static RPL_WHOREPLY: u16 = 352; pub static RPL_ENDOFWHO: u16 = 315; pub static RPL_NAMREPLY: u16 = 353; pub static RPL_ENDOFNAMES: u16 = 366; pub static RPL_LINKS: u16 = 364; pub static RPL_ENDOFLINKS: u16 = 365; pub static RPL_BANLIST: u16 = 367; pub static RPL_ENDOFBANLIST: u16 = 368; pub static RPL_INFO: u16 = 371; pub static RPL_ENDOFINFO: u16 = 374; pub static RPL_MOTDSTART: u16 = 375; pub static RPL_MOTD: u16 = 372; pub static RPL_ENDOFMOTD: u16 = 376; pub static RPL_YOUREOPER: u16 = 381; pub static RPL_REHASHING: u16 = 382; pub static RPL_YOURESERVICE: u16 = 383; pub static RPL_TIME: u16 = 391; pub static RPL_USERSSTART: u16 = 392; pub static RPL_USERS: u16 = 393; pub static RPL_ENDOFUSERS: u16 = 394; pub static RPL_NOUSERS: u16 = 395; pub static RPL_TRACELINK: u16 = 200; pub static RPL_TRACECONNECTING: u16 = 201; pub static RPL_TRACEHANDSHAKE: u16 = 202; pub static RPL_TRACEUNKNOWN: u16 = 203; pub static RPL_TRACEOPERATOR: u16 = 204; pub static RPL_TRACEUSER: u16 = 205; pub static RPL_TRACESERVER: u16 = 206; pub static RPL_TRACESERVICE: u16 = 207; pub static RPL_TRACENEWTYPE: u16 = 208; pub static RPL_TRACECLASS: u16 = 209; pub static RPL_TRACERECONNECT: u16 = 210; pub static RPL_TRACELOG: u16 = 261; pub static RPL_TRACEEND: u16 = 262; pub static RPL_STATSLINKINFO: u16 = 211; pub static RPL_STATSCOMMANDS: u16 = 212; pub static RPL_ENDOFSTATS: u16 = 219; pub static RPL_STATSUPTIME: u16 = 242; pub static RPL_STATSOLINE: u16 = 243; pub static RPL_UMODEIS: u16 = 221; pub static RPL_SERVLIST: u16 = 234; pub static RPL_SERVLISTEND: u16 = 235; pub static RPL_LUSERCLIENT: u16 = 251; pub static RPL_LUSEROP: u16 = 252; pub static RPL_LUSERUNKNOWN: u16 = 253; pub static RPL_LUSERCHANNELS: u16 = 254; pub static RPL_LUSERME: u16 = 255; pub static RPL_ADMINME: u16 = 256; pub static RPL_ADMINLOC1: u16 = 257; pub static RPL_ADMINLOC2: u16 = 258; pub static RPL_ADMINEMAIL: u16 = 259; pub static RPL_TRYAGAIN: u16 = 263; // errors pub static ERR_NOSUCHNICK: u16 = 401; // No such nick/channel pub static ERR_NOSUCHSERVER: u16 = 402; // No such server pub static ERR_NOSUCHCHANNEL: u16 = 403; // No such channel pub static ERR_CANNOTSENDTOCHAN: u16 = 404; // Cannot send to channel pub static ERR_TOOMANYCHANNELS: u16 = 405; // You have joined too many channels pub static ERR_WASNOSUCHNICK: u16 = 406; // There was no such nickname pub static ERR_TOOMANYTARGETS: u16 = 407; // Duplicate recipients. No message delivered pub static ERR_NOSUCHSERVICE: u16 = 408; // No such service pub static ERR_NOORIGIN: u16 = 409; // No origin specified pub static ERR_NORECIPIENT: u16 = 411; // No recipient given pub static ERR_NOTEXTTOSEND: u16 = 412; // No text to send pub static ERR_NOTOPLEVEL: u16 = 413; // No toplevel domain specified pub static ERR_WILDTOPLEVEL: u16 = 414; // Wildcard in toplevel domain pub static ERR_BADMASK: u16 = 415; // Bad server/host mask pub static ERR_UNKNOWNCOMMAND: u16 = 421; // Unknown command pub static ERR_NOMOTD: u16 = 422; // MOTD file is missing pub static ERR_NOADMININFO: u16 = 423; // No administrative info available pub static ERR_FILEERROR: u16 = 424; // File error pub static ERR_NONICKNAMEGIVEN: u16 = 431; // No nickname given pub static ERR_ERRONEUSNICKNAME: u16 = 432; // Erroneus nickname pub static ERR_NICKNAMEINUSE: u16 = 433; // Nickname is already in use pub static ERR_NICKCOLLISION: u16 = 436; // Nickname collision KILL pub static ERR_UNAVAILRESOURCE: u16 = 437; // Nick/channel is temporarily unavailable pub static ERR_USERNOTINCHANNEL: u16 = 441; // They aren't on that channel pub static ERR_NOTONCHANNEL: u16 = 442; // You're not on that channel pub static ERR_USERONCHANNEL: u16 = 443; // User is already on channel pub static ERR_NOLOGIN: u16 = 444; // User not logged in pub static ERR_SUMMONDISABLED: u16 = 445; // SUMMON has been disabled pub static ERR_USERSDISABLED: u16 = 446; // USERS has been disabled pub static ERR_NOTREGISTERED: u16 = 451; // You have not registered pub static ERR_NEEDMOREPARAMS: u16 = 461; // Not enough parameters pub static ERR_ALREADYREGISTERED: u16 = 462; // You may not reregister pub static ERR_NOPERMFORHOST: u16 = 463; // Your host isn't among the privileged pub static ERR_PASSWDMISMATCH: u16 = 464; // Password incorrect pub static ERR_YOUREBANNEDCREEP: u16 = 465; // You are banned from this server pub static ERR_YOUWILLBEBANNED: u16 = 466; pub static ERR_KEYSET: u16 = 467; // Channel key already set pub static ERR_CHANNELISFULL: u16 = 471; // Cannot join channel (+l) pub static ERR_UNKNOWNMODE: u16 = 472; // Unknown mode char pub static ERR_INVITEONLYCHAN: u16 = 473; // Cannot join channel (+i) pub static ERR_BANNEDFROMCHAN: u16 = 474; // Cannot join channel (+b) pub static ERR_BADCHANNELKEY: u16 = 475; // Cannot join channel (+k) pub static ERR_BADCHANMASK: u16 = 476; // Bad channel mask pub static ERR_NOCHANMODES: u16 = 477; // Channel doesn't support modes pub static ERR_BANLISTFULL: u16 = 478; // Channel list is full pub static ERR_NOPRIVILEGES: u16 = 481; // Permission denied- You're not an IRC operator pub static ERR_CHANOPRIVSNEEDED: u16 = 482; // You're not channel operator pub static ERR_CANTKILLSERVER: u16 = 483; // You can't kill a server! pub static ERR_RESTRICTED: u16 = 484; // Your connection is restricted! pub static ERR_UNIQOPPRIVSNEEDED: u16 = 485; // You're not the original channel operator pub static ERR_NOOPERHOST: u16 = 491; // No O-lines for your host pub static ERR_UMODEUNKNOWNFLAG: u16 = 501; // Unknown MODE flag pub static ERR_USERSDONTMATCH: u16 = 502; // Can't change mode for other users //unused pub static RPL_SERVICEINFO: u16 = 231; pub static RPL_ENDOFSERVICES: u16 = 232; pub static RPL_SERVICE: u16 = 233; pub static RPL_NONE: u16 = 300; pub static RPL_WHOISCHANOP: u16 = 316; pub static RPL_KILLDONE: u16 = 361; pub static RPL_CLOSING: u16 = 362; pub static RPL_CLOSEEND: u16 = 363; pub static RPL_INFOSTART: u16 = 373; pub static RPL_MYPORTIS: u16 = 384; pub static RPL_STATSCLINE: u16 = 213; pub static RPL_STATSNLINE: u16 = 214; pub static RPL_STATSILINE: u16 = 215; pub static RPL_STATSKLINE: u16 = 216; pub static RPL_STATSQLINE: u16 = 217; pub static RPL_STATSYLINE: u16 = 218; pub static RPL_STATSVLINE: u16 = 240; pub static RPL_STATSLLINE: u16 = 241; pub static RPL_STATSHLINE: u16 = 244; pub static RPL_STATSPING: u16 = 246; pub static RPL_STATSBLINE: u16 = 247; pub static RPL_STATSDLINE: u16 = 250; pub static ERR_NOSERVICEHOST: u16 = 492; // guesses pub static RPL_TOPICDATE: u16 = 333; // date the topic was set, in seconds since the epoch pub static ERR_MSGFORBIDDEN: u16 = 505; // freenode blocking privmsg from unreged users pub static MAX_MESSAGE_LENGTH: uint = 512; #[test] fn test_message_type () { assert!(!from_str::("PASS").unwrap().is_reply()); assert!(from_str::("001").unwrap().is_reply()); assert!(!from_str::("NOTACOMMAND").unwrap().is_reply()); }