diff options
| author | Austin Hellyer <[email protected]> | 2016-11-09 20:03:51 -0800 |
|---|---|---|
| committer | Austin Hellyer <[email protected]> | 2016-11-09 20:03:51 -0800 |
| commit | 96574bfd96a19254831f242620f9cdeca02a36eb (patch) | |
| tree | 222148f1fc1f38d8bfe71b504d41a1a2f80c79fa /src | |
| parent | Fix message decoding with reactions (diff) | |
| download | serenity-96574bfd96a19254831f242620f9cdeca02a36eb.tar.xz serenity-96574bfd96a19254831f242620f9cdeca02a36eb.zip | |
Map op codes via a macro
Diffstat (limited to 'src')
| -rw-r--r-- | src/client/mod.rs | 1 | ||||
| -rw-r--r-- | src/constants.rs | 86 | ||||
| -rw-r--r-- | src/model/gateway.rs | 4 | ||||
| -rw-r--r-- | src/utils/mod.rs | 26 |
4 files changed, 51 insertions, 66 deletions
diff --git a/src/client/mod.rs b/src/client/mod.rs index e010ebf..77ec3e1 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -144,6 +144,7 @@ pub enum ClientError { /// [`LiveGuild`]: ../model/struct.LiveGuild.html /// [`State`]: ../ext/state/struct.State.html GuildNotFound, + InvalidOpCode, /// When attempting to perform an action which is only available to user /// accounts. InvalidOperationAsBot, diff --git a/src/constants.rs b/src/constants.rs index e5190e0..785ee59 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -28,45 +28,21 @@ pub enum OpCode { SyncCall, } -impl OpCode { - pub fn from_num(num: u8) -> Result<OpCode> { - match num { - 0 => Ok(OpCode::Event), - 1 => Ok(OpCode::Heartbeat), - 2 => Ok(OpCode::Identify), - 3 => Ok(OpCode::StatusUpdate), - 4 => Ok(OpCode::VoiceStateUpdate), - 5 => Ok(OpCode::VoiceServerPing), - 6 => Ok(OpCode::Resume), - 7 => Ok(OpCode::Reconnect), - 8 => Ok(OpCode::GetGuildMembers), - 9 => Ok(OpCode::InvalidSession), - 10 => Ok(OpCode::Hello), - 11 => Ok(OpCode::HeartbeatAck), - 12 => Ok(OpCode::SyncGuild), - 13 => Ok(OpCode::SyncCall), - other => Err(Error::Decode("Unknown op", Value::U64(other as u64))), - } - } - - pub fn num(&self) -> u8 { - match *self { - OpCode::Event => 0, - OpCode::Heartbeat => 1, - OpCode::Identify => 2, - OpCode::StatusUpdate => 3, - OpCode::VoiceStateUpdate => 4, - OpCode::VoiceServerPing => 5, - OpCode::Resume => 6, - OpCode::Reconnect => 7, - OpCode::GetGuildMembers => 8, - OpCode::InvalidSession => 9, - OpCode::Hello => 10, - OpCode::HeartbeatAck => 11, - OpCode::SyncGuild => 12, - OpCode::SyncCall => 13, - } - } +map_nums! { OpCode; + Event 0, + Heartbeat 1, + Identify 2, + StatusUpdate 3, + VoiceStateUpdate 4, + VoiceServerPing 5, + Resume 6, + Reconnect 7, + GetGuildMembers 8, + InvalidSession 9, + Hello 10, + HeartbeatAck 11, + SyncGuild 12, + SyncCall 13, } #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -79,29 +55,11 @@ pub enum VoiceOpCode { Speaking, } -impl VoiceOpCode { - pub fn from_num(num: u8) -> Result<VoiceOpCode> { - match num { - 0 => Ok(VoiceOpCode::Identify), - 1 => Ok(VoiceOpCode::SelectProtocol), - 2 => Ok(VoiceOpCode::Hello), - 3 => Ok(VoiceOpCode::Heartbeat), - 4 => Ok(VoiceOpCode::SessionDescription), - 5 => Ok(VoiceOpCode::Speaking), - other => Err(Error::Decode("Unknown voice op", Value::U64(other as u64))), - } - } - - pub fn num(&self) -> u8 { - use self::*; - - match *self { - VoiceOpCode::Identify => 0, - VoiceOpCode::SelectProtocol => 1, - VoiceOpCode::Hello => 2, - VoiceOpCode::Heartbeat => 3, - VoiceOpCode::SessionDescription => 4, - VoiceOpCode::Speaking => 5, - } - } +map_nums! { VoiceOpCode; + Identify 0, + SelectProtocol 1, + Hello 2, + Heartbeat 3, + SessionDescription 4, + Speaking 5, } diff --git a/src/model/gateway.rs b/src/model/gateway.rs index 5748302..dfdddf2 100644 --- a/src/model/gateway.rs +++ b/src/model/gateway.rs @@ -324,7 +324,7 @@ impl GatewayEvent { let op = req!(value.get("op").and_then(|x| x.as_u64())); - match try!(OpCode::from_num(op as u8)) { + match try!(OpCode::from_num(op).ok_or(Error::Client(ClientError::InvalidOpCode))) { OpCode::Event => Ok(GatewayEvent::Dispatch( req!(try!(remove(&mut value, "s")).as_u64()), try!(Event::decode( @@ -375,7 +375,7 @@ impl VoiceEvent { let mut value = try!(into_map(value)); let op = req!(try!(remove(&mut value, "op")).as_u64()); - let op = try!(VoiceOpCode::from_num(op as u8)); + let op = try!(VoiceOpCode::from_num(op).ok_or(Error::Client(ClientError::InvalidOpCode))); if op == VoiceOpCode::Heartbeat { return Ok(VoiceEvent::KeepAlive) diff --git a/src/utils/mod.rs b/src/utils/mod.rs index e6d2b4c..103a73e 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -40,6 +40,32 @@ macro_rules! status_concat { } } +macro_rules! map_nums { + ($item:ident; $($entry:ident $value:expr,)*) => { + impl $item { + pub fn num(&self) -> u64 { + match *self { + $($item::$entry => $value,)* + } + } + + pub fn from_num(num: u64) -> Option<Self> { + match num { + $($value => Some($item::$entry),)* + _ => None, + } + } + + fn decode(value: Value) -> Result<Self> { + value.as_u64().and_then(Self::from_num).ok_or(Error::Decode( + concat!("Expected valid ", stringify!($item)), + value + )) + } + } + } +} + #[doc(hidden)] pub fn decode_array<T, F: Fn(Value) -> Result<T>>(value: Value, f: F) -> Result<Vec<T>> { into_array(value).and_then(|x| x.into_iter().map(f).collect()) |