diff options
| author | Austin Hellyer <[email protected]> | 2016-11-13 19:28:13 -0800 |
|---|---|---|
| committer | Austin Hellyer <[email protected]> | 2016-11-14 18:32:10 -0800 |
| commit | 7d22fb2a9c70e5e517b359875a0157f72e352e43 (patch) | |
| tree | ca3bcb3a76f68960563d3c38d45e21f493ce32f8 /src/model | |
| parent | Add internal module (diff) | |
| download | serenity-7d22fb2a9c70e5e517b359875a0157f72e352e43.tar.xz serenity-7d22fb2a9c70e5e517b359875a0157f72e352e43.zip | |
Add voice connection support
Diffstat (limited to 'src/model')
| -rw-r--r-- | src/model/gateway.rs | 61 | ||||
| -rw-r--r-- | src/model/utils.rs | 6 | ||||
| -rw-r--r-- | src/model/voice.rs | 97 |
3 files changed, 103 insertions, 61 deletions
diff --git a/src/model/gateway.rs b/src/model/gateway.rs index ee62dd5..aa3d995 100644 --- a/src/model/gateway.rs +++ b/src/model/gateway.rs @@ -1,7 +1,7 @@ use std::collections::{BTreeMap, HashMap}; use super::utils::*; use super::*; -use ::constants::{OpCode, VoiceOpCode}; +use ::constants::OpCode; use ::internal::prelude::*; use ::utils::decode_array; @@ -355,65 +355,6 @@ impl GatewayEvent { } } -#[derive(Debug, Clone)] -pub enum VoiceEvent { - Handshake { - heartbeat_interval: u64, - port: u16, - ssrc: u32, - modes: Vec<String>, - }, - Ready { - mode: String, - secret_key: Vec<u8>, - }, - SpeakingUpdate { - user_id: UserId, - ssrc: u32, - speaking: bool, - }, - KeepAlive, - Unknown(u64, Value) -} - -impl VoiceEvent { - pub fn decode(value: Value) -> Result<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).ok_or(Error::Client(ClientError::InvalidOpCode))); - - if op == VoiceOpCode::Heartbeat { - return Ok(VoiceEvent::KeepAlive) - } - - let mut value = try!(remove(&mut value, "d").and_then(into_map)); - if op == VoiceOpCode::Hello { - missing!(value, VoiceEvent::Handshake { - heartbeat_interval: req!(try!(remove(&mut value, "heartbeat_interval")).as_u64()), - modes: try!(decode_array(try!(remove(&mut value, "modes")), into_string)), - port: req!(try!(remove(&mut value, "port")).as_u64()) as u16, - ssrc: req!(try!(remove(&mut value, "ssrc")).as_u64()) as u32, - }) - } else if op == VoiceOpCode::SessionDescription { - missing!(value, VoiceEvent::Ready { - mode: try!(remove(&mut value, "mode").and_then(into_string)), - secret_key: try!(decode_array(try!(remove(&mut value, "secret_key")), - |v| Ok(req!(v.as_u64()) as u8) - )), - }) - } else if op == VoiceOpCode::Speaking { - missing!(value, VoiceEvent::SpeakingUpdate { - user_id: try!(remove(&mut value, "user_id").and_then(UserId::decode)), - ssrc: req!(try!(remove(&mut value, "ssrc")).as_u64()) as u32, - speaking: req!(try!(remove(&mut value, "speaking")).as_bool()), - }) - } else { - Ok(VoiceEvent::Unknown(op as u64, Value::Object(value))) - } - } -} - /// Event received over a websocket connection #[derive(Clone, Debug)] pub enum Event { diff --git a/src/model/utils.rs b/src/model/utils.rs index f0108e9..f85a30f 100644 --- a/src/model/utils.rs +++ b/src/model/utils.rs @@ -35,7 +35,11 @@ macro_rules! missing { #[macro_escape] macro_rules! req { ($opt:expr) => { - try!($opt.ok_or(Error::Decode(concat!("Type mismatch in model:", line!(), ": ", stringify!($opt)), Value::Null))) + try!($opt.ok_or(Error::Decode(concat!("Type mismatch in model:", + line!(), + ": ", + stringify!($opt)), + Value::Null))) } } diff --git a/src/model/voice.rs b/src/model/voice.rs index e69de29..a888029 100644 --- a/src/model/voice.rs +++ b/src/model/voice.rs @@ -0,0 +1,97 @@ +use super::utils::{into_map, into_string, remove, warn_field}; +use super::UserId; +use ::constants::VoiceOpCode; +use ::internal::prelude::*; +use ::utils::decode_array; + +#[derive(Clone, Debug)] +pub struct VoiceHandshake { + pub heartbeat_interval: u64, + pub ip: Option<String>, + pub modes: Vec<String>, + pub port: u16, + pub ssrc: u32, +} + +#[derive(Clone, Debug)] +pub struct VoiceHeartbeat { + pub heartbeat_interval: u64, +} + +#[derive(Clone, Debug)] +pub struct VoiceHello { + pub heartbeat_interval: u64, + pub modes: Vec<String>, + pub port: u16, + pub ssrc: u32, +} + +#[derive(Clone, Debug)] +pub struct VoiceReady { + pub mode: String, + pub secret_key: Vec<u8>, +} + +#[derive(Clone, Debug)] +pub struct VoiceSpeaking { + pub speaking: bool, + pub ssrc: u32, + pub user_id: UserId, +} + +#[derive(Clone, Debug)] +pub enum VoiceEvent { + Handshake(VoiceHandshake), + Heartbeat(VoiceHeartbeat), + Hello(VoiceHello), + Ready(VoiceReady), + Speaking(VoiceSpeaking), + KeepAlive, + Unknown(VoiceOpCode, Value) +} + +impl VoiceEvent { + pub fn decode(value: Value) -> Result<VoiceEvent> { + let mut value = try!(into_map(value)); + let op = req!(try!(remove(&mut value, "op")).as_u64()); + let mut map = try!(remove(&mut value, "d").and_then(into_map)); + + match try!(VoiceOpCode::from_num(op).ok_or(Error::Client(ClientError::InvalidOpCode))) { + VoiceOpCode::Heartbeat => { + missing!(map, VoiceEvent::Heartbeat(VoiceHeartbeat { + heartbeat_interval: req!(try!(remove(&mut value, "heartbeat_interval")).as_u64()), + })) + }, + VoiceOpCode::Hello => { + missing!(map, VoiceEvent::Hello(VoiceHello { + heartbeat_interval: req!(try!(remove(&mut map, "heartbeat_interval")) + .as_u64()), + modes: try!(decode_array(try!(remove(&mut map, "modes")), + into_string)), + port: req!(try!(remove(&mut map, "port")) + .as_u64()) as u16, + ssrc: req!(try!(remove(&mut map, "ssrc")) + .as_u64()) as u32, + })) + }, + VoiceOpCode::KeepAlive => Ok(VoiceEvent::KeepAlive), + VoiceOpCode::SessionDescription => { + missing!(map, VoiceEvent::Ready(VoiceReady { + mode: try!(remove(&mut map, "mode") + .and_then(into_string)), + secret_key: try!(decode_array(try!(remove(&mut map, "secret_key")), + |v| Ok(req!(v.as_u64()) as u8) + )), + })) + }, + VoiceOpCode::Speaking => { + missing!(map, VoiceEvent::Speaking(VoiceSpeaking { + speaking: req!(try!(remove(&mut map, "speaking")).as_bool()), + ssrc: req!(try!(remove(&mut map, "ssrc")).as_u64()) as u32, + user_id: try!(remove(&mut map, "user_id").and_then(UserId::decode)), + })) + } + other => Ok(VoiceEvent::Unknown(other, Value::Object(map))), + } + } +} |