1 use std::env;
2 use std::path::PathBuf;
3
4 use crate::BaseDirs;
5 use crate::UserDirs;
6 use crate::ProjectDirs;
7
base_dirs() -> Option<BaseDirs>8 pub fn base_dirs() -> Option<BaseDirs> {
9 if let Some(home_dir) = dirs_sys_next::home_dir() {
10 let cache_dir = env::var_os("XDG_CACHE_HOME") .and_then(dirs_sys_next::is_absolute_path).unwrap_or_else(|| home_dir.join(".cache"));
11 let config_dir = env::var_os("XDG_CONFIG_HOME").and_then(dirs_sys_next::is_absolute_path).unwrap_or_else(|| home_dir.join(".config"));
12 let data_dir = env::var_os("XDG_DATA_HOME") .and_then(dirs_sys_next::is_absolute_path).unwrap_or_else(|| home_dir.join(".local/share"));
13 let data_local_dir = data_dir.clone();
14 let runtime_dir = env::var_os("XDG_RUNTIME_DIR").and_then(dirs_sys_next::is_absolute_path);
15 let executable_dir =
16 env::var_os("XDG_BIN_HOME").and_then(dirs_sys_next::is_absolute_path).unwrap_or_else(|| {
17 let mut new_dir = data_dir.clone(); new_dir.pop(); new_dir.push("bin"); new_dir });
18
19 let base_dirs = BaseDirs {
20 home_dir: home_dir,
21 cache_dir: cache_dir,
22 config_dir: config_dir,
23 data_dir: data_dir,
24 data_local_dir: data_local_dir,
25 executable_dir: Some(executable_dir),
26 runtime_dir: runtime_dir
27 };
28 Some(base_dirs)
29 } else {
30 None
31 }
32 }
33
user_dirs() -> Option<UserDirs>34 pub fn user_dirs() -> Option<UserDirs> {
35 if let Some(home_dir) = dirs_sys_next::home_dir() {
36 let data_dir = env::var_os("XDG_DATA_HOME").and_then(dirs_sys_next::is_absolute_path).unwrap_or_else(|| home_dir.join(".local/share"));
37 let font_dir = data_dir.join("fonts");
38 let mut user_dirs_map = dirs_sys_next::user_dirs(&home_dir);
39
40 let user_dirs = UserDirs {
41 home_dir: home_dir,
42 audio_dir: user_dirs_map.remove("MUSIC"),
43 desktop_dir: user_dirs_map.remove("DESKTOP"),
44 document_dir: user_dirs_map.remove("DOCUMENTS"),
45 download_dir: user_dirs_map.remove("DOWNLOAD"),
46 font_dir: Some(font_dir),
47 picture_dir: user_dirs_map.remove("PICTURES"),
48 public_dir: user_dirs_map.remove("PUBLICSHARE"),
49 template_dir: user_dirs_map.remove("TEMPLATES"),
50 video_dir: user_dirs_map.remove("VIDEOS")
51 };
52 Some(user_dirs)
53 } else {
54 None
55 }
56 }
57
project_dirs_from_path(project_path: PathBuf) -> Option<ProjectDirs>58 pub fn project_dirs_from_path(project_path: PathBuf) -> Option<ProjectDirs> {
59 if let Some(home_dir) = dirs_sys_next::home_dir() {
60 let cache_dir = env::var_os("XDG_CACHE_HOME") .and_then(dirs_sys_next::is_absolute_path).unwrap_or_else(|| home_dir.join(".cache")).join(&project_path);
61 let config_dir = env::var_os("XDG_CONFIG_HOME").and_then(dirs_sys_next::is_absolute_path).unwrap_or_else(|| home_dir.join(".config")).join(&project_path);
62 let data_dir = env::var_os("XDG_DATA_HOME") .and_then(dirs_sys_next::is_absolute_path).unwrap_or_else(|| home_dir.join(".local/share")).join(&project_path);
63 let data_local_dir = data_dir.clone();
64 let runtime_dir = env::var_os("XDG_RUNTIME_DIR").and_then(dirs_sys_next::is_absolute_path).map(|o| o.join(&project_path));
65
66 let project_dirs = ProjectDirs {
67 project_path: project_path,
68 cache_dir: cache_dir,
69 config_dir: config_dir,
70 data_dir: data_dir,
71 data_local_dir: data_local_dir,
72 runtime_dir: runtime_dir
73 };
74 Some(project_dirs)
75 } else {
76 None
77 }
78 }
79
project_dirs_from(_qualifier: &str, _organization: &str, application: &str) -> Option<ProjectDirs>80 pub fn project_dirs_from(_qualifier: &str, _organization: &str, application: &str) -> Option<ProjectDirs> {
81 ProjectDirs::from_path(PathBuf::from(&trim_and_lowercase_then_replace_spaces(application, "")))
82 }
83
trim_and_lowercase_then_replace_spaces(name: &str, replacement: &str) -> String84 fn trim_and_lowercase_then_replace_spaces(name: &str, replacement: &str) -> String {
85 let mut buf = String::with_capacity(name.len());
86 let mut parts = name.split_whitespace();
87 let mut current_part = parts.next();
88 let replace = !replacement.is_empty();
89 while current_part.is_some() {
90 let value = current_part.unwrap().to_lowercase();
91 buf.push_str(&value);
92 current_part = parts.next();
93 if replace && current_part.is_some() {
94 buf.push_str(replacement);
95 }
96 }
97 buf
98 }
99
100 #[cfg(test)]
101 mod tests {
102 use crate::lin::trim_and_lowercase_then_replace_spaces;
103
104 #[test]
test_trim_and_lowercase_then_replace_spaces()105 fn test_trim_and_lowercase_then_replace_spaces() {
106 let input1 = "Bar App";
107 let actual1 = trim_and_lowercase_then_replace_spaces(input1, "-");
108 let expected1 = "bar-app";
109 assert_eq!(expected1, actual1);
110
111 let input2 = "BarApp-Foo";
112 let actual2 = trim_and_lowercase_then_replace_spaces(input2, "-");
113 let expected2 = "barapp-foo";
114 assert_eq!(expected2, actual2);
115
116 let input3 = " Bar App ";
117 let actual3 = trim_and_lowercase_then_replace_spaces(input3, "-");
118 let expected3 = "bar-app";
119 assert_eq!(expected3, actual3);
120
121 let input4 = " Bar App ";
122 let actual4 = trim_and_lowercase_then_replace_spaces(input4, "-");
123 let expected4 = "bar-app";
124 assert_eq!(expected4, actual4);
125 }
126
127 #[test]
test_file_user_dirs_exists()128 fn test_file_user_dirs_exists() {
129 let base_dirs = crate::BaseDirs::new();
130 let user_dirs_file = base_dirs.unwrap().config_dir().join("user-dirs.dirs");
131 println!("{:?} exists: {:?}", user_dirs_file, user_dirs_file.exists());
132 }
133 }
134