From 37d146b907250ab186f88d9eaf589a23b16faf29 Mon Sep 17 00:00:00 2001 From: Michel de Graaf Date: Fri, 24 Jul 2026 13:50:20 +0200 Subject: [PATCH] fix(persist): use XDG paths on macOS Config and state now live in ~/.config/soulseek-rs and ~/.local/share/soulseek-rs instead of Application Support. --- soulseek-rs/src/persist/paths.rs | 37 ++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/soulseek-rs/src/persist/paths.rs b/soulseek-rs/src/persist/paths.rs index 9aaa367..b002f57 100644 --- a/soulseek-rs/src/persist/paths.rs +++ b/soulseek-rs/src/persist/paths.rs @@ -1,3 +1,4 @@ +#[cfg(not(target_os = "macos"))] use directories::ProjectDirs; use std::path::PathBuf; @@ -9,7 +10,7 @@ pub fn config_file() -> Option { if let Ok(dir) = std::env::var("SOULSEEK_CONFIG_DIR") { return Some(PathBuf::from(dir).join("config.toml")); } - project_dirs().map(|d| d.config_dir().join("config.toml")) + config_dir().map(|d| d.join("config.toml")) } #[must_use] @@ -17,9 +18,41 @@ pub fn state_dir() -> Option { if let Ok(dir) = std::env::var("SOULSEEK_STATE_DIR") { return Some(PathBuf::from(dir)); } - project_dirs().map(|d| d.data_dir().join("state")) + data_dir().map(|d| d.join("state")) } +// macOS follows the XDG layout (~/.config, ~/.local/share) instead of +// Application Support, by request. Other platforms keep the crate defaults. +#[cfg(target_os = "macos")] +fn config_dir() -> Option { + xdg_dir("XDG_CONFIG_HOME", ".config") +} + +#[cfg(target_os = "macos")] +fn data_dir() -> Option { + xdg_dir("XDG_DATA_HOME", ".local/share") +} + +#[cfg(target_os = "macos")] +fn xdg_dir(env: &str, fallback: &str) -> Option { + let base = match std::env::var_os(env) { + Some(dir) if !dir.is_empty() => PathBuf::from(dir), + _ => directories::UserDirs::new()?.home_dir().join(fallback), + }; + Some(base.join("soulseek-rs")) +} + +#[cfg(not(target_os = "macos"))] +fn config_dir() -> Option { + project_dirs().map(|d| d.config_dir().to_path_buf()) +} + +#[cfg(not(target_os = "macos"))] +fn data_dir() -> Option { + project_dirs().map(|d| d.data_dir().to_path_buf()) +} + +#[cfg(not(target_os = "macos"))] fn project_dirs() -> Option { ProjectDirs::from("", "", "soulseek-rs") }