1use std::path::PathBuf;
16use thiserror::Error;
17
18#[non_exhaustive]
20#[derive(Error, Debug)]
21pub enum DirectoryError {
22 #[error("Could not find the requested {0} directory on the system")]
24 NotFound(&'static str),
25}
26
27pub fn config_path() -> Result<PathBuf, DirectoryError> {
34 #[cfg(target_os = "macos")]
35 return config_path_macos();
36
37 #[cfg(target_os = "linux")]
38 return config_path_linux();
39
40 #[cfg(target_os = "windows")]
41 return config_path_windows();
42}
43
44pub fn cache_path() -> Result<PathBuf, DirectoryError> {
51 #[cfg(target_os = "macos")]
52 return cache_path_macos();
53
54 #[cfg(target_os = "linux")]
55 return cache_path_linux();
56
57 #[cfg(target_os = "windows")]
58 return cache_path_windows();
59}
60
61#[inline]
62#[cfg(target_os = "macos")]
63#[allow(clippy::missing_docs_in_private_items, clippy::missing_errors_doc)]
64fn config_path_macos() -> Result<PathBuf, DirectoryError> {
65 let home = std::env::home_dir().ok_or(DirectoryError::NotFound("home"))?;
66
67 Ok(home.join("Library/Application Support/DungeonRS/config"))
68}
69
70#[inline]
71#[cfg(target_os = "linux")]
72#[allow(clippy::missing_docs_in_private_items, clippy::missing_errors_doc)]
73fn config_path_linux() -> Result<PathBuf, DirectoryError> {
74 let path = std::env::var("XDG_CONFIG_HOME")
75 .map(|home| PathBuf::from(home).join("DungeonRS"))
76 .map_err(|_| {
77 std::env::var("HOME").map(|home| PathBuf::from(home).join(".config/DungeonRS"))
78 })
79 .map_err(|_| DirectoryError::NotFound("XDG_CONFIG_HOME"))?;
80
81 Ok(path)
82}
83
84#[inline]
85#[cfg(target_os = "windows")]
86#[allow(clippy::missing_docs_in_private_items, clippy::missing_errors_doc)]
87fn config_path_windows() -> Result<PathBuf, DirectoryError> {
88 let home = known_folders::get_known_folder_path(known_folders::KnownFolder::RoamingAppData)
89 .ok_or_else(|| DirectoryError::NotFound("RoamingAppData"))?;
90
91 Ok(home.join("DungeonRS/config"))
92}
93
94#[inline]
95#[cfg(target_os = "macos")]
96#[allow(clippy::missing_docs_in_private_items, clippy::missing_errors_doc)]
97fn cache_path_macos() -> Result<PathBuf, DirectoryError> {
98 let home = std::env::home_dir().ok_or(DirectoryError::NotFound("home"))?;
99
100 Ok(home.join("Library/Cache/DungeonRS"))
101}
102
103#[inline]
104#[cfg(target_os = "linux")]
105#[allow(clippy::missing_docs_in_private_items, clippy::missing_errors_doc)]
106fn cache_path_linux() -> Result<PathBuf, DirectoryError> {
107 let path = std::env::var("XDG_CACHE_HOME")
108 .map(|home| PathBuf::from(home).join("DungeonRS"))
109 .map_err(|_| std::env::var("HOME").map(|home| PathBuf::from(home).join(".cache/DungeonRS")))
110 .map_err(|_| DirectoryError::NotFound("XDG_CACHE_HOME"))?;
111
112 Ok(path)
113}
114
115#[inline]
116#[cfg(target_os = "windows")]
117#[allow(clippy::missing_docs_in_private_items, clippy::missing_errors_doc)]
118fn cache_path_windows() -> Result<PathBuf, DirectoryError> {
119 let home = known_folders::get_known_folder_path(known_folders::KnownFolder::LocalAppData)
120 .ok_or_else(|| DirectoryError::NotFound("LocalAppData"))?;
121
122 Ok(home.join("DungeonRS/cache"))
123}