| extern crate dirs_sys; |
| |
| use std::env; |
| use std::path::PathBuf; |
| |
| use BaseDirs; |
| use UserDirs; |
| use ProjectDirs; |
| |
| pub fn base_dirs() -> Option<BaseDirs> { |
| if let Some(home_dir) = dirs_sys::home_dir() { |
| let cache_dir = env::var_os("XDG_CACHE_HOME") .and_then(dirs_sys::is_absolute_path).unwrap_or_else(|| home_dir.join(".cache")); |
| let config_dir = env::var_os("XDG_CONFIG_HOME").and_then(dirs_sys::is_absolute_path).unwrap_or_else(|| home_dir.join(".config")); |
| let config_local_dir = config_dir.clone(); |
| let data_dir = env::var_os("XDG_DATA_HOME") .and_then(dirs_sys::is_absolute_path).unwrap_or_else(|| home_dir.join(".local/share")); |
| let data_local_dir = data_dir.clone(); |
| let preference_dir = config_dir.clone(); |
| let runtime_dir = env::var_os("XDG_RUNTIME_DIR").and_then(dirs_sys::is_absolute_path); |
| let state_dir = env::var_os("XDG_STATE_HOME") .and_then(dirs_sys::is_absolute_path).unwrap_or_else(|| home_dir.join(".local/state")); |
| let executable_dir = env::var_os("XDG_BIN_HOME") .and_then(dirs_sys::is_absolute_path).unwrap_or_else(|| home_dir.join(".local/bin")); |
| |
| let base_dirs = BaseDirs { |
| home_dir: home_dir, |
| cache_dir: cache_dir, |
| config_dir: config_dir, |
| config_local_dir: config_local_dir, |
| data_dir: data_dir, |
| data_local_dir: data_local_dir, |
| executable_dir: Some(executable_dir), |
| preference_dir: preference_dir, |
| runtime_dir: runtime_dir, |
| state_dir: Some(state_dir) |
| }; |
| Some(base_dirs) |
| } else { |
| None |
| } |
| } |
| |
| pub fn user_dirs() -> Option<UserDirs> { |
| if let Some(home_dir) = dirs_sys::home_dir() { |
| let data_dir = env::var_os("XDG_DATA_HOME").and_then(dirs_sys::is_absolute_path).unwrap_or_else(|| home_dir.join(".local/share")); |
| let font_dir = data_dir.join("fonts"); |
| let mut user_dirs_map = dirs_sys::user_dirs(&home_dir); |
| |
| let user_dirs = UserDirs { |
| home_dir: home_dir, |
| audio_dir: user_dirs_map.remove("MUSIC"), |
| desktop_dir: user_dirs_map.remove("DESKTOP"), |
| document_dir: user_dirs_map.remove("DOCUMENTS"), |
| download_dir: user_dirs_map.remove("DOWNLOAD"), |
| font_dir: Some(font_dir), |
| picture_dir: user_dirs_map.remove("PICTURES"), |
| public_dir: user_dirs_map.remove("PUBLICSHARE"), |
| template_dir: user_dirs_map.remove("TEMPLATES"), |
| video_dir: user_dirs_map.remove("VIDEOS") |
| }; |
| Some(user_dirs) |
| } else { |
| None |
| } |
| } |
| |
| pub fn project_dirs_from_path(project_path: PathBuf) -> Option<ProjectDirs> { |
| if let Some(home_dir) = dirs_sys::home_dir() { |
| 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); |
| 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); |
| let config_local_dir = config_dir.clone(); |
| 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); |
| let data_local_dir = data_dir.clone(); |
| let preference_dir = config_dir.clone(); |
| let runtime_dir = env::var_os("XDG_RUNTIME_DIR").and_then(dirs_sys::is_absolute_path).map(|o| o.join(&project_path)); |
| 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); |
| |
| let project_dirs = ProjectDirs { |
| project_path: project_path, |
| cache_dir: cache_dir, |
| config_dir: config_dir, |
| config_local_dir: config_local_dir, |
| data_dir: data_dir, |
| data_local_dir: data_local_dir, |
| preference_dir: preference_dir, |
| runtime_dir: runtime_dir, |
| state_dir: Some(state_dir) |
| }; |
| Some(project_dirs) |
| } else { |
| None |
| } |
| } |
| |
| pub fn project_dirs_from(_qualifier: &str, _organization: &str, application: &str) -> Option<ProjectDirs> { |
| ProjectDirs::from_path(PathBuf::from(&trim_and_lowercase_then_replace_spaces(application, ""))) |
| } |
| |
| fn trim_and_lowercase_then_replace_spaces(name: &str, replacement: &str) -> String { |
| let mut buf = String::with_capacity(name.len()); |
| let mut parts = name.split_whitespace(); |
| let mut current_part = parts.next(); |
| let replace = !replacement.is_empty(); |
| while current_part.is_some() { |
| let value = current_part.unwrap().to_lowercase(); |
| buf.push_str(&value); |
| current_part = parts.next(); |
| if replace && current_part.is_some() { |
| buf.push_str(replacement); |
| } |
| } |
| buf |
| } |
| |
| #[cfg(test)] |
| mod tests { |
| use lin::trim_and_lowercase_then_replace_spaces; |
| |
| #[test] |
| fn test_trim_and_lowercase_then_replace_spaces() { |
| let input1 = "Bar App"; |
| let actual1 = trim_and_lowercase_then_replace_spaces(input1, "-"); |
| let expected1 = "bar-app"; |
| assert_eq!(expected1, actual1); |
| |
| let input2 = "BarApp-Foo"; |
| let actual2 = trim_and_lowercase_then_replace_spaces(input2, "-"); |
| let expected2 = "barapp-foo"; |
| assert_eq!(expected2, actual2); |
| |
| let input3 = " Bar App "; |
| let actual3 = trim_and_lowercase_then_replace_spaces(input3, "-"); |
| let expected3 = "bar-app"; |
| assert_eq!(expected3, actual3); |
| |
| let input4 = " Bar App "; |
| let actual4 = trim_and_lowercase_then_replace_spaces(input4, "-"); |
| let expected4 = "bar-app"; |
| assert_eq!(expected4, actual4); |
| } |
| |
| #[test] |
| fn test_file_user_dirs_exists() { |
| let base_dirs = ::BaseDirs::new(); |
| let user_dirs_file = base_dirs.unwrap().config_dir().join("user-dirs.dirs"); |
| println!("{:?} exists: {:?}", user_dirs_file, user_dirs_file.exists()); |
| } |
| } |