Move some common methods into Connection trait

This commit is contained in:
Patrick Auernig 2018-04-03 12:03:08 +02:00
parent 51cd4413f7
commit b8e4697555
4 changed files with 58 additions and 78 deletions

View File

@ -1,19 +1,50 @@
use std::{ use std::{
io::{Write, Read},
marker::Sized, marker::Sized,
fmt::Debug fmt::Debug,
path::PathBuf,
}; };
use models::{Payload, OpCode}; use models::{Payload, Message, OpCode};
use error::Result; use error::Result;
pub trait Connection pub trait Connection
where Self: Sized where Self: Sized
{ {
type Socket: Write + Read;
fn socket(&mut self) -> &mut Self::Socket;
fn ipc_path() -> PathBuf;
fn connect() -> Result<Self>; fn connect() -> Result<Self>;
fn send<T>(&mut self, opcode: OpCode, payload: T) -> Result<()> fn socket_path(n: u8) -> PathBuf {
where T: Payload + Debug; Self::ipc_path().join(format!("discord-ipc-{}", n))
}
fn recv(&mut self) -> Result<Vec<u8>>; fn send<T>(&mut self, opcode: OpCode, payload: T) -> Result<()>
where T: Payload + Debug
{
debug!("payload: {:#?}", payload);
match Message::new(opcode, payload).encode() {
Err(why) => error!("{:?}", why),
Ok(bytes) => {
self.socket().write_all(bytes.as_ref())?;
debug!("sent opcode: {:?}", opcode);
self.recv()?;
}
};
Ok(())
}
fn recv(&mut self) -> Result<Vec<u8>> {
let mut buf: Vec<u8> = vec![0; 1024];
let n = self.socket().read(buf.as_mut_slice())?;
buf.resize(n, 0);
debug!("{:?}", Message::decode(&buf));
Ok(buf)
}
} }

View File

@ -1,14 +1,11 @@
use std::{ use std::{
os::unix::net::UnixStream,
io::{Write, Read},
time, time,
path::PathBuf, path::PathBuf,
env, env,
fmt::Debug os::unix::net::UnixStream,
}; };
use super::base::Connection; use super::base::Connection;
use models::{Payload, Message, OpCode};
use error::Result; use error::Result;
@ -16,7 +13,17 @@ pub struct UnixConnection {
socket: UnixStream, socket: UnixStream,
} }
impl UnixConnection { impl Connection for UnixConnection {
type Socket = UnixStream;
fn connect() -> Result<Self> {
let connection_name = Self::socket_path(0);
let socket = UnixStream::connect(connection_name)?;
socket.set_write_timeout(Some(time::Duration::from_secs(30)))?;
socket.set_read_timeout(Some(time::Duration::from_secs(30)))?;
Ok(Self { socket })
}
fn ipc_path() -> PathBuf { fn ipc_path() -> PathBuf {
let tmp = env::var("XDG_RUNTIME_DIR") let tmp = env::var("XDG_RUNTIME_DIR")
.or_else(|_| env::var("TMPDIR")) .or_else(|_| env::var("TMPDIR"))
@ -30,40 +37,7 @@ impl UnixConnection {
PathBuf::from(tmp) PathBuf::from(tmp)
} }
fn socket_path(n: u8) -> PathBuf { fn socket(&mut self) -> &mut Self::Socket {
Self::ipc_path().join(format!("discord-ipc-{}", n)) &mut self.socket
}
}
impl Connection for UnixConnection {
fn connect() -> Result<Self> {
let connection_name = Self::socket_path(0);
let socket = UnixStream::connect(connection_name)?;
socket.set_write_timeout(Some(time::Duration::from_secs(30)))?;
socket.set_read_timeout(Some(time::Duration::from_secs(30)))?;
Ok(Self { socket })
}
fn send<T>(&mut self, opcode: OpCode, payload: T) -> Result<()>
where T: Payload + Debug
{
debug!("payload: {:#?}", payload);
match Message::new(opcode, payload).encode() {
Err(why) => error!("{:?}", why),
Ok(bytes) => {
self.socket.write_all(bytes.as_ref())?;
debug!("sent opcode: {:?}", opcode);
self.recv()?;
}
};
Ok(())
}
fn recv(&mut self) -> Result<Vec<u8>> {
let mut buf: Vec<u8> = vec![0; 1024];
let n = self.socket.read(buf.as_mut_slice())?;
buf.resize(n, 0);
debug!("{:?}", Message::decode(&buf));
Ok(buf)
} }
} }

View File

@ -1,10 +1,6 @@
extern crate named_pipe;
use std::{ use std::{
io::{Write, Read},
time, time,
path::PathBuf, path::PathBuf,
fmt::Debug
}; };
use super::base::Connection; use super::base::Connection;
@ -17,17 +13,9 @@ pub struct WindowsConnection {
socket: PipeClient, socket: PipeClient,
} }
impl WindowsConnection {
fn ipc_path() -> PathBuf {
PathBuf::from(r"\\.\pipe\")
}
fn socket_path(n: u8) -> PathBuf {
Self::ipc_path().join(format!("discord-ipc-{}", n))
}
}
impl Connection for WindowsConnection { impl Connection for WindowsConnection {
type Socket = PipeClient;
fn connect() -> Result<Self> { fn connect() -> Result<Self> {
let connection_name = Self::socket_path(0); let connection_name = Self::socket_path(0);
let mut socket = PipeClient::connect(connection_name)?; let mut socket = PipeClient::connect(connection_name)?;
@ -36,26 +24,11 @@ impl Connection for WindowsConnection {
Ok(Self { socket }) Ok(Self { socket })
} }
fn send<T>(&mut self, opcode: OpCode, payload: T) -> Result<()> fn ipc_path() -> PathBuf {
where T: Payload + Debug PathBuf::from(r"\\.\pipe\")
{
debug!("payload: {:#?}", payload);
match Message::new(opcode, payload).encode() {
Err(why) => error!("{:?}", why),
Ok(bytes) => {
self.socket.write_all(bytes.as_ref())?;
debug!("sent opcode: {:?}", opcode);
self.recv()?;
}
};
Ok(())
} }
fn recv(&mut self) -> Result<Vec<u8>> { fn socket(&mut self) -> &mut Self::Socket {
let mut buf: Vec<u8> = vec![0; 1024]; &mut self.socket
let n = self.socket.read(buf.as_mut_slice())?;
buf.resize(n, 0);
debug!("{:?}", Message::decode(&buf));
Ok(buf)
} }
} }

View File

@ -7,6 +7,8 @@ extern crate serde_json;
extern crate byteorder; extern crate byteorder;
extern crate uuid; extern crate uuid;
extern crate libc; extern crate libc;
#[cfg(windows)]
extern crate named_pipe;
#[macro_use] #[macro_use]
mod macros; mod macros;