aboutsummaryrefslogtreecommitdiff
path: root/src/internal
diff options
context:
space:
mode:
authorAustin Hellyer <[email protected]>2016-11-13 19:28:13 -0800
committerAustin Hellyer <[email protected]>2016-11-14 18:32:10 -0800
commit7d22fb2a9c70e5e517b359875a0157f72e352e43 (patch)
treeca3bcb3a76f68960563d3c38d45e21f493ce32f8 /src/internal
parentAdd internal module (diff)
downloadserenity-7d22fb2a9c70e5e517b359875a0157f72e352e43.tar.xz
serenity-7d22fb2a9c70e5e517b359875a0157f72e352e43.zip
Add voice connection support
Diffstat (limited to 'src/internal')
-rw-r--r--src/internal/mod.rs7
-rw-r--r--src/internal/timer.rs45
-rw-r--r--src/internal/ws_impl.rs60
3 files changed, 112 insertions, 0 deletions
diff --git a/src/internal/mod.rs b/src/internal/mod.rs
index b9d7209..9dd4676 100644
--- a/src/internal/mod.rs
+++ b/src/internal/mod.rs
@@ -1 +1,8 @@
pub mod prelude;
+pub mod ws_impl;
+
+#[cfg(feature = "voice")]
+mod timer;
+
+#[cfg(feature = "voice")]
+pub use self::timer::Timer;
diff --git a/src/internal/timer.rs b/src/internal/timer.rs
new file mode 100644
index 0000000..cc846b3
--- /dev/null
+++ b/src/internal/timer.rs
@@ -0,0 +1,45 @@
+use std::thread;
+use std::time::Duration as StdDuration;
+use time::{self, Duration, Timespec};
+
+pub struct Timer {
+ due: Timespec,
+ duration: Duration,
+}
+
+impl Timer {
+ pub fn new(duration_in_ms: u64) -> Timer {
+ let duration = Duration::milliseconds(duration_in_ms as i64);
+
+ Timer {
+ due: time::get_time() + duration,
+ duration: duration,
+ }
+ }
+
+ pub fn await(&mut self) {
+ let diff = self.due - time::get_time();
+
+ if diff > time::Duration::zero() {
+ let amount = diff.num_milliseconds() as u64;
+
+ thread::sleep(StdDuration::from_millis(amount));
+ }
+
+ self.due = self.due + self.duration;
+ }
+
+ pub fn check(&mut self) -> bool {
+ if time::get_time() >= self.due {
+ self.due = self.due + self.duration;
+
+ true
+ } else {
+ false
+ }
+ }
+
+ pub fn reset(&mut self) {
+ self.due = time::get_time() + self.duration;
+ }
+}
diff --git a/src/internal/ws_impl.rs b/src/internal/ws_impl.rs
new file mode 100644
index 0000000..ab91dae
--- /dev/null
+++ b/src/internal/ws_impl.rs
@@ -0,0 +1,60 @@
+use flate2::read::ZlibDecoder;
+use serde_json;
+use websocket::client::{Receiver, Sender};
+use websocket::message::{Message as WsMessage, Type as WsType};
+use websocket::stream::WebSocketStream;
+use websocket::ws::receiver::Receiver as WsReceiver;
+use websocket::ws::sender::Sender as WsSender;
+use ::client::ConnectionError;
+use ::internal::prelude::*;
+
+pub trait ReceiverExt {
+ fn recv_json<F, T>(&mut self, decode: F) -> Result<T>
+ where F: FnOnce(Value) -> Result<T>;
+}
+
+pub trait SenderExt {
+ fn send_json(&mut self, value: &Value) -> Result<()>;
+}
+
+impl ReceiverExt for Receiver<WebSocketStream> {
+ fn recv_json<F, T>(&mut self, decode: F) -> Result<T> where F: FnOnce(Value) -> Result<T> {
+ let message: WsMessage = try!(self.recv_message());
+
+ if message.opcode == WsType::Close {
+ let representation = String::from_utf8_lossy(&message.payload)
+ .into_owned();
+
+ Err(Error::Connection(ConnectionError::Closed(message.cd_status_code,
+ representation)))
+ } else if message.opcode == WsType::Binary || message.opcode == WsType::Text {
+ let json: Value = if message.opcode == WsType::Binary {
+ try!(serde_json::from_reader(ZlibDecoder::new(&message.payload[..])))
+ } else {
+ try!(serde_json::from_reader(&message.payload[..]))
+ };
+
+ decode(json).map_err(|err| {
+ warn!("Error decoding: {}",
+ String::from_utf8_lossy(&message.payload));
+
+ err
+ })
+ } else {
+ let representation = String::from_utf8_lossy(&message.payload)
+ .into_owned();
+
+ Err(Error::Connection(ConnectionError::Closed(None,
+ representation)))
+ }
+ }
+}
+
+impl SenderExt for Sender<WebSocketStream> {
+ fn send_json(&mut self, value: &Value) -> Result<()> {
+ serde_json::to_string(value)
+ .map(WsMessage::text)
+ .map_err(Error::from)
+ .and_then(|m| self.send_message(&m).map_err(Error::from))
+ }
+}