use std::io;
use std::path::PathBuf;
const SOCKET_NAME: &str = "debugger-cli";
#[cfg(unix)]
pub fn socket_path() -> PathBuf {
if let Ok(runtime_dir) = std::env::var("XDG_RUNTIME_DIR") {
return PathBuf::from(runtime_dir)
.join(SOCKET_NAME)
.join("daemon.sock");
}
let uid = unsafe { libc::getuid() };
PathBuf::from(format!("/tmp/{}-{}", SOCKET_NAME, uid)).join("daemon.sock")
}
#[cfg(windows)]
pub fn socket_path() -> PathBuf {
let username = std::env::var("USERNAME").unwrap_or_else(|_| "default".to_string());
PathBuf::from(format!("{}-{}", SOCKET_NAME, username))
}
#[cfg(unix)]
pub fn socket_name() -> String {
socket_path().to_string_lossy().into_owned()
}
#[cfg(windows)]
pub fn socket_name() -> String {
let username = std::env::var("USERNAME").unwrap_or_else(|_| "default".to_string());
format!("{}-{}", SOCKET_NAME, username)
}
#[cfg(unix)]
pub fn ensure_socket_dir() -> io::Result<PathBuf> {
let socket = socket_path();
let dir = socket.parent().ok_or_else(|| {
io::Error::new(io::ErrorKind::InvalidInput, "Invalid socket path")
})?;
if !dir.exists() {
std::fs::create_dir_all(dir)?;
use std::os::unix::fs::PermissionsExt;
std::fs::set_permissions(dir, std::fs::Permissions::from_mode(0o700))?;
}
Ok(dir.to_path_buf())
}
#[cfg(windows)]
pub fn ensure_socket_dir() -> io::Result<PathBuf> {
Ok(PathBuf::new())
}
#[cfg(unix)]
pub fn remove_socket() -> io::Result<()> {
let path = socket_path();
if path.exists() {
std::fs::remove_file(&path)?;
}
Ok(())
}
#[cfg(windows)]
pub fn remove_socket() -> io::Result<()> {
Ok(())
}
pub fn config_dir() -> Option<PathBuf> {
directories::ProjectDirs::from("", "", SOCKET_NAME)
.map(|dirs| dirs.config_dir().to_path_buf())
}
pub fn config_path() -> Option<PathBuf> {
config_dir().map(|dir| dir.join("config.toml"))
}
pub fn log_dir() -> Option<PathBuf> {
directories::ProjectDirs::from("", "", SOCKET_NAME)
.map(|dirs| dirs.data_dir().join("logs"))
}
pub fn ensure_config_dir() -> io::Result<Option<PathBuf>> {
if let Some(dir) = config_dir() {
if !dir.exists() {
std::fs::create_dir_all(&dir)?;
}
Ok(Some(dir))
} else {
Ok(None)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_socket_path_is_valid() {
let path = socket_path();
assert!(!path.as_os_str().is_empty());
}
#[test]
fn test_config_dir_is_valid() {
let dir = config_dir();
assert!(dir.is_some());
}
}