keyfork/keyforkd-client/src/lib.rs

74 lines
2.2 KiB
Rust
Raw Normal View History

use std::{collections::HashMap, os::unix::net::UnixStream, path::PathBuf};
use keyfork_frame::{try_decode_from, try_encode_to, DecodeError, EncodeError};
use keyforkd_models::{Request, Response /* Error as KeyforkdError */};
#[cfg(test)]
mod tests;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Neither KEYFORK_SOCKET_PATH nor XDG_RUNTIME_DIR were set")]
EnvVarsNotFound,
#[error("Socket was unable to connect to {1}: {0}")]
Connect(std::io::Error, PathBuf),
#[error("Could not write to or from the socket: {0}")]
Io(#[from] std::io::Error),
#[error("Could not perform bincode transformation: {0}")]
Bincode(#[from] Box<bincode::ErrorKind>),
#[error("Could not perform frame transformation: {0}")]
FrameEnc(#[from] EncodeError),
#[error("Could not perform frame transformation: {0}")]
FrameDec(#[from] DecodeError),
}
pub type Result<T, E = Error> = std::result::Result<T, E>;
pub fn get_socket() -> Result<UnixStream, Error> {
let socket_vars = std::env::vars()
.filter(|(key, _)| ["XDG_RUNTIME_DIR", "KEYFORKD_SOCKET_PATH"].contains(&key.as_str()))
.collect::<HashMap<String, String>>();
let mut socket_path: PathBuf;
#[allow(clippy::single_match_else)]
match socket_vars.get("KEYFORKD_SOCKET_PATH") {
Some(occupied) => {
socket_path = PathBuf::from(occupied);
}
None => {
socket_path = PathBuf::from(
socket_vars
.get("XDG_RUNTIME_DIR")
.ok_or(Error::EnvVarsNotFound)?,
);
socket_path.extend(["keyforkd", "keyforkd.sock"]);
}
}
UnixStream::connect(&socket_path).map_err(|e| Error::Connect(e, socket_path))
}
#[derive(Debug)]
pub struct Client {
socket: UnixStream,
}
impl Client {
pub fn new(socket: UnixStream) -> Self {
Self { socket }
}
pub fn discover_socket() -> Result<Self> {
get_socket().map(|socket| Self { socket })
}
pub fn request(&mut self, req: &Request) -> Result<Response> {
try_encode_to(&bincode::serialize(&req)?, &mut self.socket)?;
let resp = try_decode_from(&mut self.socket)?;
bincode::deserialize(&resp).map_err(From::from)
}
}