diff --git a/crates/xy/src/main.rs b/crates/xy/src/main.rs index 662ece1..303b93b 100644 --- a/crates/xy/src/main.rs +++ b/crates/xy/src/main.rs @@ -1,3 +1,8 @@ +mod paths; +#[allow(dead_code)] +mod pidfile; + fn main() { - println!("xy: not implemented yet"); + let p = paths::Paths::resolve().unwrap(); + eprintln!("xy: socket would be at {}", p.socket.display()); } diff --git a/crates/xy/src/paths.rs b/crates/xy/src/paths.rs new file mode 100644 index 0000000..15df94d --- /dev/null +++ b/crates/xy/src/paths.rs @@ -0,0 +1,42 @@ +use etcetera::base_strategy::{BaseStrategy, Xdg}; +use std::path::PathBuf; + +#[derive(Debug, Clone)] +pub struct Paths { + pub config_dir: PathBuf, + pub state_dir: PathBuf, + pub log_dir: PathBuf, + pub socket: PathBuf, + pub pidfile: PathBuf, +} + +impl Paths { + pub fn resolve() -> std::io::Result { + let xdg = Xdg::new().map_err(std::io::Error::other)?; + let config_dir = xdg.config_dir().join("xy").join("servers"); + let state_dir = xdg.state_dir().unwrap_or_else(|| xdg.data_dir()).join("xy"); + let log_dir = state_dir.join("logs"); + let socket = std::env::var_os("XDG_RUNTIME_DIR") + .map(|p| PathBuf::from(p).join("xy.sock")) + .unwrap_or_else(|| state_dir.join("xy.sock")); + let pidfile = state_dir.join("xy.pid"); + Ok(Self { config_dir, state_dir, log_dir, socket, pidfile }) + } + + pub fn ensure_dirs(&self) -> std::io::Result<()> { + std::fs::create_dir_all(&self.state_dir)?; + std::fs::create_dir_all(&self.log_dir)?; + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn resolves_without_panicking() { + let p = Paths::resolve().unwrap(); + assert!(p.pidfile.starts_with(&p.state_dir)); + } +}