upstream_rs/utils/
static_paths.rs1use anyhow::{Context, Result};
2use std::path::PathBuf;
3
4pub struct AppDirs {
6 pub user_dir: PathBuf,
7 pub config_dir: PathBuf,
8 pub data_dir: PathBuf,
9 pub packages_dir: PathBuf,
10 pub cache_dir: PathBuf,
11 pub metadata_dir: PathBuf,
12}
13
14impl Default for AppDirs {
15 fn default() -> Self {
16 Self::new().expect("failed to determine upstream app directories")
17 }
18}
19
20impl AppDirs {
21 pub fn new() -> Result<Self> {
22 let user_dir =
23 dirs::home_dir().context("Failed to determine the current user's home directory")?;
24 let config_dir = dirs::config_dir()
25 .context("Failed to determine the current user's config directory")?
26 .join("upstream");
27
28 let data_dir = user_dir.join(".upstream");
29 let packages_dir = data_dir.join("packages");
30 let cache_dir = data_dir.join("cache");
31 let metadata_dir = data_dir.join("metadata");
32
33 Ok(Self {
34 user_dir,
35 config_dir,
36 data_dir,
37 packages_dir,
38 cache_dir,
39 metadata_dir,
40 })
41 }
42}
43
44pub struct ConfigPaths {
46 pub config_file: PathBuf,
47 pub packages_file: PathBuf,
48 pub metadata_file: PathBuf,
49 pub trust_file: PathBuf,
50 pub paths_file: PathBuf,
51 pub paths_nu_file: PathBuf,
52}
53
54impl ConfigPaths {
55 pub fn new(dirs: &AppDirs) -> Self {
56 Self {
57 config_file: dirs.config_dir.join("config.toml"),
58 packages_file: dirs.metadata_dir.join("packages.json"),
59 metadata_file: dirs.metadata_dir.join("metadata.json"),
60 trust_file: dirs.metadata_dir.join("trust.json"),
61 paths_file: dirs.metadata_dir.join("paths.sh"),
62 paths_nu_file: dirs.metadata_dir.join("paths.nu"),
63 }
64 }
65}
66
67pub struct InstallPaths {
69 pub appimages_dir: PathBuf,
70 pub binaries_dir: PathBuf,
71 pub archives_dir: PathBuf,
72 pub rollback_dir: PathBuf,
73 pub tmp_dir: PathBuf,
74}
75
76impl InstallPaths {
77 pub fn new(dirs: &AppDirs) -> Self {
78 Self {
79 appimages_dir: dirs.packages_dir.join("appimages"),
80 binaries_dir: dirs.packages_dir.join("binaries"),
81 archives_dir: dirs.packages_dir.join("archives"),
82 rollback_dir: dirs.data_dir.join("rollback"),
83 tmp_dir: dirs.data_dir.join("temp"),
84 }
85 }
86}
87
88pub struct IntegrationPaths {
90 pub symlinks_dir: PathBuf,
91 pub xdg_applications_dir: PathBuf,
92 pub icons_dir: PathBuf,
93 pub bash_completions_dir: PathBuf,
94 pub fish_completions_dir: PathBuf,
95 pub zsh_completions_dir: PathBuf,
96}
97
98impl IntegrationPaths {
99 pub fn new(dirs: &AppDirs) -> Self {
100 Self {
101 symlinks_dir: dirs.data_dir.join("symlinks"),
102 icons_dir: dirs.data_dir.join("icons"),
103 xdg_applications_dir: dirs.user_dir.join(".local/share/applications"),
104 bash_completions_dir: dirs
105 .user_dir
106 .join(".local/share/bash-completion/completions"),
107 fish_completions_dir: dirs.user_dir.join(".config/fish/completions"),
108 zsh_completions_dir: dirs.user_dir.join(".local/share/zsh/site-functions"),
109 }
110 }
111}
112
113pub struct UpstreamPaths {
115 pub dirs: AppDirs,
116 pub config: ConfigPaths,
117 pub install: InstallPaths,
118 pub integration: IntegrationPaths,
119}
120
121impl Default for UpstreamPaths {
122 fn default() -> Self {
123 Self::new().expect("failed to determine upstream paths")
124 }
125}
126
127impl UpstreamPaths {
128 pub fn new() -> Result<Self> {
129 let dirs = AppDirs::new()?;
130 Ok(Self {
131 config: ConfigPaths::new(&dirs),
132 install: InstallPaths::new(&dirs),
133 integration: IntegrationPaths::new(&dirs),
134 dirs,
135 })
136 }
137}
138
139#[cfg(test)]
140mod tests {
141 use super::UpstreamPaths;
142
143 #[test]
144 fn upstream_paths_are_composed_from_base_directories() {
145 let paths = UpstreamPaths::new().expect("paths");
146
147 assert_eq!(
148 paths.config.config_file,
149 paths.dirs.config_dir.join("config.toml")
150 );
151 assert_eq!(
152 paths.config.packages_file,
153 paths.dirs.metadata_dir.join("packages.json")
154 );
155 assert_eq!(
156 paths.config.metadata_file,
157 paths.dirs.metadata_dir.join("metadata.json")
158 );
159 assert_eq!(
160 paths.config.trust_file,
161 paths.dirs.metadata_dir.join("trust.json")
162 );
163 assert_eq!(
164 paths.config.paths_nu_file,
165 paths.dirs.metadata_dir.join("paths.nu")
166 );
167 assert_eq!(
168 paths.install.binaries_dir,
169 paths.dirs.packages_dir.join("binaries")
170 );
171 assert_eq!(
172 paths.dirs.packages_dir,
173 paths.dirs.data_dir.join("packages")
174 );
175 assert_eq!(paths.dirs.cache_dir, paths.dirs.data_dir.join("cache"));
176 assert_eq!(
177 paths.integration.symlinks_dir,
178 paths.dirs.data_dir.join("symlinks")
179 );
180 assert_eq!(
181 paths.integration.fish_completions_dir,
182 paths.dirs.user_dir.join(".config/fish/completions")
183 );
184 assert_eq!(
185 paths.install.rollback_dir,
186 paths.dirs.data_dir.join("rollback")
187 );
188 assert_eq!(paths.install.tmp_dir, paths.dirs.data_dir.join("temp"));
189 }
190}