Skip to main content

verso/util/
paths.rs

1use std::path::{Path, PathBuf};
2
3pub struct Paths {
4    root: PathBuf,
5}
6
7impl Paths {
8    /// Deterministic layout rooted at `root` (useful in tests).
9    pub fn for_root(root: &Path) -> Self {
10        Self {
11            root: root.to_path_buf(),
12        }
13    }
14
15    /// Real XDG layout derived from the user's environment.
16    pub fn from_env() -> anyhow::Result<Self> {
17        let dirs = directories::ProjectDirs::from("app", "", "verso")
18            .ok_or_else(|| anyhow::anyhow!("could not determine XDG paths"))?;
19        // We compose our own layout so data_dir/state_dir/config_dir each end in "verso".
20        let root = dirs
21            .data_dir()
22            .parent()
23            .ok_or_else(|| anyhow::anyhow!("unexpected XDG root"))?
24            .parent()
25            .unwrap_or(dirs.data_dir())
26            .to_path_buf();
27        Ok(Self { root })
28    }
29
30    pub fn data_dir(&self) -> PathBuf {
31        self.root.join("share").join("verso")
32    }
33    pub fn config_dir(&self) -> PathBuf {
34        self.root.join("config").join("verso")
35    }
36    pub fn state_dir(&self) -> PathBuf {
37        self.root.join("state").join("verso")
38    }
39
40    pub fn db_file(&self) -> PathBuf {
41        self.data_dir().join("verso.db")
42    }
43    pub fn config_file(&self) -> PathBuf {
44        self.config_dir().join("config.toml")
45    }
46    pub fn log_dir(&self) -> PathBuf {
47        self.state_dir().join("log")
48    }
49}