Add Connection trait and implement UnixConnection
This commit is contained in:
parent
43c8a6af5f
commit
53bab6857e
|
@ -4,12 +4,13 @@ extern crate discord_rpc_client;
|
|||
use simplelog::*;
|
||||
use std::{thread, time};
|
||||
use discord_rpc_client::Client as DiscordRPC;
|
||||
use discord_rpc_client::UnixConnection as Connection;
|
||||
|
||||
fn main() {
|
||||
TermLogger::init(LevelFilter::Debug, Config::default()).unwrap();
|
||||
|
||||
let mut drpc =
|
||||
DiscordRPC::new(425407036495495169)
|
||||
DiscordRPC::<Connection>::new(425407036495495169)
|
||||
.and_then(|rpc| rpc.start())
|
||||
.expect("Failed to start client");
|
||||
|
||||
|
|
|
@ -1,26 +1,24 @@
|
|||
use std::env;
|
||||
use std::io::{Write, Read, Result};
|
||||
use std::os::unix::net::UnixStream;
|
||||
use std::time;
|
||||
use std::fmt::Debug;
|
||||
use models::{Message, Handshake, Payload};
|
||||
use std::io::Result;
|
||||
use connection::Connection;
|
||||
use models::Handshake;
|
||||
#[cfg(feature = "rich_presence")]
|
||||
use models::{SetActivityArgs, SetActivity};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Client {
|
||||
pub struct Client<T>
|
||||
where T: Connection
|
||||
{
|
||||
client_id: u64,
|
||||
version: u32,
|
||||
socket: UnixStream,
|
||||
socket: T,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
impl<T> Client<T>
|
||||
where T: Connection
|
||||
{
|
||||
pub fn new(client_id: u64) -> Result<Self> {
|
||||
let connection_name = Self::ipc_path();
|
||||
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 { version: 1, client_id, socket })
|
||||
let socket = T::connect()?;
|
||||
Ok(Self { version: 1, client_id, socket})
|
||||
}
|
||||
|
||||
pub fn start(mut self) -> Result<Self> {
|
||||
|
@ -33,7 +31,7 @@ impl Client {
|
|||
where F: FnOnce(SetActivity) -> SetActivity
|
||||
{
|
||||
let args = SetActivityArgs::command(f(SetActivity::new()));
|
||||
self.send(1, args)?;
|
||||
self.socket.send(1, args)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -42,35 +40,7 @@ impl Client {
|
|||
fn handshake(&mut self) -> Result<()> {
|
||||
let client_id = self.client_id;
|
||||
let version = self.version;
|
||||
self.send(0, Handshake::new(client_id, version))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn ipc_path() -> String {
|
||||
let tmp = env::var("XDG_RUNTIME_DIR").unwrap_or("/tmp".into());
|
||||
format!("{}/discord-ipc-0", tmp)
|
||||
}
|
||||
|
||||
fn send<T>(&mut self, opcode: u32, 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.receive()?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn receive(&mut self) -> Result<()> {
|
||||
let mut buf: Vec<u8> = Vec::with_capacity(1024);
|
||||
self.socket.read(buf.as_mut_slice())?;
|
||||
debug!("{:?}", buf);
|
||||
self.socket.send(0, Handshake::new(client_id, version))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
use std::io::Result;
|
||||
use std::marker::Sized;
|
||||
use std::fmt::Debug;
|
||||
use models::Payload;
|
||||
|
||||
pub trait Connection
|
||||
where Self: Sized
|
||||
{
|
||||
fn connect() -> Result<Self>;
|
||||
|
||||
fn send<T>(&mut self, opcode: u32, payload: T) -> Result<()>
|
||||
where T: Payload + Debug;
|
||||
|
||||
fn recv(&mut self) -> Result<Vec<u8>>;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
mod base;
|
||||
|
||||
#[cfg(unix)]
|
||||
mod unix;
|
||||
|
||||
pub use self::base::Connection;
|
||||
#[cfg(unix)]
|
||||
pub use self::unix::UnixConnection;
|
|
@ -0,0 +1,65 @@
|
|||
use std::os::unix::net::UnixStream;
|
||||
use std::io::{Write, Read, Result};
|
||||
use std::time;
|
||||
use std::path::PathBuf;
|
||||
use std::env;
|
||||
use std::fmt::Debug;
|
||||
use models::Payload;
|
||||
|
||||
use models::Message;
|
||||
use super::base::Connection;
|
||||
|
||||
pub struct UnixConnection {
|
||||
socket: UnixStream,
|
||||
}
|
||||
|
||||
impl UnixConnection {
|
||||
fn ipc_path() -> PathBuf {
|
||||
let tmp = env::var("XDG_RUNTIME_DIR")
|
||||
.or_else(|_| env::var("TMPDIR"))
|
||||
.or_else(|_| {
|
||||
match env::temp_dir().to_str() {
|
||||
None => Err("Failed to convert temp_dir"),
|
||||
Some(tmp) => Ok(tmp.to_string())
|
||||
}
|
||||
})
|
||||
.unwrap_or("/tmp".to_string());
|
||||
PathBuf::from(tmp)
|
||||
}
|
||||
|
||||
fn socket_path(n: u8) -> PathBuf {
|
||||
Self::ipc_path().join(format!("discord-ipc-{}", n))
|
||||
}
|
||||
}
|
||||
|
||||
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: u32, 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::with_capacity(1024);
|
||||
self.socket.read(buf.as_mut_slice())?;
|
||||
debug!("{:?}", buf);
|
||||
Ok(buf)
|
||||
}
|
||||
}
|
|
@ -12,8 +12,12 @@ extern crate uuid;
|
|||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
mod connection;
|
||||
mod models;
|
||||
pub mod client;
|
||||
|
||||
pub use models::prelude;
|
||||
pub use client::Client;
|
||||
pub use models::prelude;
|
||||
|
||||
#[cfg(unix)]
|
||||
pub use connection::UnixConnection;
|
||||
|
|
Loading…
Reference in New Issue