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