diff --git a/keyforkd/src/lib.rs b/keyforkd/src/lib.rs new file mode 100644 index 0000000..770d370 --- /dev/null +++ b/keyforkd/src/lib.rs @@ -0,0 +1,70 @@ +use std::{collections::HashMap, path::PathBuf}; + +use keyfork_mnemonic_util::Mnemonic; +use tower::ServiceBuilder; + +#[cfg(feature = "tracing")] +use tracing::debug; + +mod error; +mod middleware; +mod server; +mod service; +use error::KeyforkdError; +use server::UnixServer; +use service::Keyforkd; + +pub async fn start_and_run_server(mnemonic: Mnemonic) -> Result<(), Box> { + let service = ServiceBuilder::new() + .layer(middleware::SerdeLayer::new()) + .service(Keyforkd::new(mnemonic)); + + let runtime_vars = std::env::vars() + .filter(|(key, _)| ["XDG_RUNTIME_DIR", "KEYFORKD_SOCKET_PATH"].contains(&key.as_str())) + .collect::>(); + let mut runtime_path: PathBuf; + #[allow(clippy::single_match_else)] + match runtime_vars.get("KEYFORKD_SOCKET_PATH") { + Some(occupied) => { + runtime_path = PathBuf::from(occupied); + } + None => { + runtime_path = PathBuf::from( + runtime_vars + .get("XDG_RUNTIME_DIR") + .ok_or(KeyforkdError::NoSocketPath)?, + ); + runtime_path.push("keyforkd"); + #[cfg(feature = "tracing")] + debug!("ensuring directory exists: {}", runtime_path.display()); + if !runtime_path.is_dir() { + tokio::fs::create_dir(&runtime_path).await?; + } + runtime_path.push("keyforkd.sock"); + } + } + + #[cfg(feature = "tracing")] + debug!( + "binding UNIX socket in runtime dir: {}", + runtime_path.display() + ); + + let mut server = match UnixServer::bind(&runtime_path) { + Ok(s) => s, + Err(e) => { + #[cfg(feature = "tracing")] + debug!(%e, "Encountered error attempting to bind socket: {}", runtime_path.display()); + return Err(e.into()); + } + }; + match server.run(service).await { + Ok(_) => (), + Err(e) => { + #[cfg(feature = "tracing")] + debug!(%e, "Encountered error while running"); + } + } + + Ok(()) +} diff --git a/keyforkd/src/main.rs b/keyforkd/src/main.rs index 7d40281..eb333e3 100644 --- a/keyforkd/src/main.rs +++ b/keyforkd/src/main.rs @@ -1,9 +1,6 @@ -use std::{collections::HashMap, path::PathBuf}; - use keyfork_mnemonic_util::Mnemonic; use tokio::io::{self, AsyncBufReadExt, BufReader}; -use tower::ServiceBuilder; #[cfg(feature = "tracing")] use tracing::debug; @@ -15,14 +12,6 @@ use tracing_subscriber::{ registry, }; -mod error; -mod server; -mod service; -mod middleware; -use error::KeyforkdError; -use server::UnixServer; -use service::Keyforkd; - type Result> = std::result::Result; async fn load_mnemonic() -> Result { @@ -54,55 +43,5 @@ async fn main() -> Result<(), Box> { debug!("reading mnemonic from standard input"); let mnemonic = load_mnemonic().await?; - let service = ServiceBuilder::new() - .layer(middleware::SerdeLayer::new()) - .service(Keyforkd::new(mnemonic)); - - let runtime_vars = std::env::vars() - .filter(|(key, _)| ["XDG_RUNTIME_DIR", "KEYFORKD_SOCKET_PATH"].contains(&key.as_str())) - .collect::>(); - let mut runtime_path: PathBuf; - #[allow(clippy::single_match_else)] - match runtime_vars.get("KEYFORKD_SOCKET_PATH") { - Some(occupied) => { - runtime_path = PathBuf::from(occupied); - } - None => { - runtime_path = PathBuf::from( - runtime_vars - .get("XDG_RUNTIME_DIR") - .ok_or(KeyforkdError::NoSocketPath)?, - ); - runtime_path.push("keyforkd"); - #[cfg(feature = "tracing")] - debug!("ensuring directory exists: {}", runtime_path.display()); - if !runtime_path.is_dir() { - tokio::fs::create_dir(&runtime_path).await?; - } - runtime_path.push("keyforkd.sock"); - } - } - - #[cfg(feature = "tracing")] - debug!( - "binding UNIX socket in runtime dir: {}", - runtime_path.display() - ); - - let mut server = match UnixServer::bind(&runtime_path) { - Ok(s) => s, - Err(e) => { - #[cfg(feature = "tracing")] - debug!(%e, "Encountered error attempting to bind socket: {}", runtime_path.display()); - return Err(e.into()); - } - }; - match server.run(service).await { - Ok(_) => (), - Err(e) => { - #[cfg(feature = "tracing")] - debug!(%e, "Encountered error while running"); - } - } - Ok(()) + keyforkd::start_and_run_server(mnemonic).await }