diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json new file mode 100644 index 0000000..60a3382 --- /dev/null +++ b/.cargo_vcs_info.json @@ -0,0 +1,5 @@ +{ + "git": { + "sha1": "836c5412ea8d5980c8b24e867a093d9c97e5a4e2" + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..98e5fcf --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +target +**/*.rs.bk +Cargo.lock diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..0c36cda --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,55 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +> **Types of changes**: +> +> - **Added**: for new features. +> - **Changed**: for changes in existing functionality. +> - **Deprecated**: for soon-to-be removed features. +> - **Removed**: for now removed features. +> - **Fixed**: for any bug fixes. +> - **Security**: in case of vulnerabilities. + +## [Unreleased] + +## [v0.3.0] - 2020-09-26 + +### Changed + +- change `AppUI` to `use_xdg_on_macos` + +### Removed + +- remove `home_dir` and `is_absolute_path` from public API + +## [0.2.0] - 2019-06-10 + +### Changed + +- Change prefix parameter from `AsRef` to `&str` + +## [0.1.2] - 2019-06-08 + +### Added + +- Derive `Clone` and `Debug` for `AppDirs` and `UserDirs` + +## [0.1.1] - 2019-06-08 + +### Fixed + +- Fixed app name prefix for `AppDirs` + +## [0.1.0] - 2019-06-08 + +Initial release + +[Unreleased]: https://github.com/cjbassi/platform-dirs-rs/compare/v0.3.0...HEAD +[v0.3.0]: https://github.com/cjbassi/platform-dirs-rs/compare/0.2.0...v0.3.0 +[0.2.0]: https://github.com/cjbassi/platform-dirs-rs/compare/0.1.2...0.2.0 +[0.1.2]: https://github.com/cjbassi/platform-dirs-rs/compare/0.1.1...0.1.2 +[0.1.1]: https://github.com/cjbassi/platform-dirs-rs/compare/0.1.0...0.1.1 +[0.1.0]: https://github.com/cjbassi/platform-dirs-rs/compare/4afc9b7218db1f2847203951ff3e1493b3d9ef38...0.1.0 diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..5ebc627 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,167 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "blake2b_simd" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg", + "cfg-if", + "lazy_static", +] + +[[package]] +name = "dirs-next" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cbcf9241d9e8d106295bd496bbe2e9cffd5fa098f2a8c9e2bbcbf09773c11a8" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c60f7b8a8953926148223260454befb50c751d3c50e1c178c4fd1ace4083c9a" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "getrandom" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235" + +[[package]] +name = "platform-dirs" +version = "0.3.0" +dependencies = [ + "dirs-next", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_users" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" +dependencies = [ + "getrandom", + "redox_syscall", + "rust-argon2", +] + +[[package]] +name = "rust-argon2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dab61250775933275e84053ac235621dfb739556d5c54a2f2e9313b7cf43a19" +dependencies = [ + "base64", + "blake2b_simd", + "constant_time_eq", + "crossbeam-utils", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..8bc0e54 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,23 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +edition = "2018" +name = "platform-dirs" +version = "0.3.0" +authors = ["Caleb Bassi "] +description = "A library for obtaining platform dependant directory paths for application and user directories" +readme = "README.md" +license = "MIT" +repository = "https://github.com/cjbassi/platform-dirs-rs" +[dependencies.dirs-next] +version = "1.0.1" diff --git a/Cargo.toml.orig b/Cargo.toml.orig new file mode 100644 index 0000000..e05e9e0 --- /dev/null +++ b/Cargo.toml.orig @@ -0,0 +1,12 @@ +[package] +name = "platform-dirs" +version = "0.3.0" +authors = ["Caleb Bassi "] +description = "A library for obtaining platform dependant directory paths for application and user directories" +readme = "README.md" +license = "MIT" +repository = "https://github.com/cjbassi/platform-dirs-rs" +edition = "2018" + +[dependencies] +dirs-next = "1.0.1" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d8003c6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2019 Caleb Bassi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..d9fb731 --- /dev/null +++ b/README.md @@ -0,0 +1,121 @@ +# platform-dirs-rs + +[![crates.io](https://img.shields.io/crates/v/platform-dirs.svg)](https://crates.io/crates/platform-dirs) +[![docs.rs](https://docs.rs/platform-dirs/badge.svg)](https://docs.rs/platform-dirs) + +A Rust library for obtaining platform dependent directory paths for application and user directories. + +Uses the following standards: +- Linux/*BSD: [XDG Base Directories] and [XDG User Directories] +- macOS: [Standard Directories] +- Windows: [Known Folder] + +[XDG Base Directories]: https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html +[XDG user directories]: https://www.freedesktop.org/wiki/Software/xdg-user-dirs/ +[Known Folder]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457.aspx +[Standard Directories]: https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW6 + +## Installation + +Add the following to your Cargo.toml: + +```toml +[dependencies] +platform-dirs = "0.3.0" +``` + +## Examples + +### Obtaining paths + +```rust +use platform_dirs::{AppDirs, UserDirs}; + +fn main() { + let app_dirs = AppDirs::new(Some("name"), false).unwrap(); + dbg!(&app_dirs); + // AppDirs { + // cache_dir: "/home/cjbassi/.cache/name", + // config_dir: "/home/cjbassi/.config/name", + // data_dir: "/home/cjbassi/.local/share/name", + // state_dir: "/home/cjbassi/.local/state/name" + // } + + let user_dirs = UserDirs::new().unwrap(); + dbg!(&user_dirs); + // UserDirs { + // desktop_dir: "/home/cjbassi/Desktop", + // document_dir: "/home/cjbassi/Documents", + // download_dir: "/home/cjbassi/Downloads", + // music_dir: "/home/cjbassi/Music", + // picture_dir: "/home/cjbassi/Pictures", + // public_dir: "/home/cjbassi/Public", + // video_dir: "/home/cjbassi/Videos" + // } +} +``` + +### Opening config file + +```rust +use std::fs::{self, File}; + +use platform_dirs::AppDirs; + +fn main() { + let app_dirs = AppDirs::new(Some("name"), true).unwrap(); + let config_file_path = app_dirs.config_dir.join("config-file"); + + fs::create_dir_all(&app_dirs.config_dir).unwrap(); + + let file = if config_file_path.exists() { + File::open(config_file_path).unwrap() + } else { + File::create(config_file_path).unwrap() + }; +} +``` + +## Path list + +### AppDirs + +Directory | Windows | Linux/*BSD | macOS +-----------|--------------------------------------------------------|--------------------------------------|------------------------------------ +cache_dir | `%LOCALAPPDATA%` (`C:\Users\%USERNAME%\AppData\Local`) | `$XDG_CACHE_HOME` (`~/.cache`) | `~/Library/Caches` +config_dir | `%APPDATA%` (`C:\Users\%USERNAME%\AppData\Roaming`) | `$XDG_CONFIG_HOME` (`~/.config`) | `~/Library/Application Support` +data_dir | `%LOCALAPPDATA%` (`C:\Users\%USERNAME%\AppData\Local`) | `$XDG_DATA_HOME` (`~/.local/share`) | `~/Library/Application Support` +state_dir | `%LOCALAPPDATA%` (`C:\Users\%USERNAME%\AppData\Local`) | `$XDG_STATE_HOME` (`~/.local/state`) | `~/Library/Application Support` + +### UserDirs + +Directory | Windows | Linux/*BSD | macOS +-------------|-----------------------------------------------------------|-------------------------------------|------------------ +desktop_dir | `{FOLDERID_Desktop}` (`C:\Users\%USERNAME%\Desktop`) | `$XDG_DESKTOP_DIR` (`~/Desktop`) | `~/Desktop` +document_dir | `{FOLDERID_Documents}` (`C:\Users\%USERNAME%\Documents`) | `$XDG_DOCUMENTS_DIR` (`~/Documents`) | `~/Documents` +download_dir | `{FOLDERID_Downloads}` (`C:\Users\%USERNAME%\Downloads`) | `$XDG_DOWNLOAD_DIR` (`~/Downloads`) | `~/Downloads` +music_dir | `{FOLDERID_Music}` (`C:\Users\%USERNAME%\Music`) | `$XDG_MUSIC_DIR` (`~/Music`) | `~/Music` +picture_dir | `{FOLDERID_Pictures}` (`C:\Users\%USERNAME%\Pictures`) | `$XDG_PICTURES_DIR` (`~/Pictures`) | `~/Pictures` +public_dir | `{FOLDERID_Public}` (`C:\Users\%USERNAME%\Public`) | `$XDG_PUBLICSHARE_DIR` (`~/Public`) | `~/Public` +video_dir | `{FOLDERID_Videos}` (`C:\Users\%USERNAME%\Videos`) | `$XDG_VIDEOS_DIR` (`~/Videos`) | `~/Movies` + +## Comparisons + +platform-dirs differs from [dirs-rs](https://github.com/soc/dirs-rs) and [directories-rs](https://github.com/soc/directories-rs) in several ways: + +- allows for using the XDG spec on macOS for CLI apps +- changes the config directory on macOS from `Library/Preferences` to `Library/Application Support` + - `Library/Preferences` is supposed to be used for macOS unique plist preferences: [info](https://www.reddit.com/r/rust/comments/8hbzyx/can_people_here_give_the_dirs_and_directories/dyj4qtk/) +- only includes directories that are cross platform + - `AppDirs`: + - removes `data_local_dir` + - `UserDirs`: + - removes `runtime_dir`, `executable_dir` +- provides a simpler API than directories-rs + - the fields of `UserDirs` are no longer `Options` + - the struct fields are now publicly accessible + - combines the `ProjectDirs` struct into `AppDirs` +- adds `state_dir` to `AppDirs` + - documentation can be found [here](https://wiki.debian.org/XDGBaseDirectorySpecification) at the bottom of the page + - used for stateful application data like logs, history, etc +- on Linux, returns default platforms values for the `UserDirs` if they are not set instead of returning `None` diff --git a/examples/basic.rs b/examples/basic.rs new file mode 100644 index 0000000..11f0458 --- /dev/null +++ b/examples/basic.rs @@ -0,0 +1,24 @@ +use platform_dirs::{AppDirs, UserDirs}; + +fn main() { + let app_dirs = AppDirs::new(Some("name"), false).unwrap(); + dbg!(&app_dirs); + // AppDirs { + // cache_dir: "/home/cjbassi/.cache/name", + // config_dir: "/home/cjbassi/.config/name", + // data_dir: "/home/cjbassi/.local/share/name", + // state_dir: "/home/cjbassi/.local/state/name" + // } + + let user_dirs = UserDirs::new().unwrap(); + dbg!(&user_dirs); + // UserDirs { + // desktop_dir: "/home/cjbassi/Desktop", + // document_dir: "/home/cjbassi/Documents", + // download_dir: "/home/cjbassi/Downloads", + // music_dir: "/home/cjbassi/Music", + // picture_dir: "/home/cjbassi/Pictures", + // public_dir: "/home/cjbassi/Public", + // video_dir: "/home/cjbassi/Videos" + // } +} diff --git a/examples/config_file.rs b/examples/config_file.rs new file mode 100644 index 0000000..d3e76bf --- /dev/null +++ b/examples/config_file.rs @@ -0,0 +1,16 @@ +use std::fs::{self, File}; + +use platform_dirs::AppDirs; + +fn main() { + let app_dirs = AppDirs::new(Some("name"), true).unwrap(); + let config_file_path = app_dirs.config_dir.join("config-file"); + + fs::create_dir_all(&app_dirs.config_dir).unwrap(); + + let file = if config_file_path.exists() { + File::open(config_file_path).unwrap() + } else { + File::create(config_file_path).unwrap() + }; +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..1c04a6b --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,198 @@ +use std::env; +use std::path::{Path, PathBuf}; + +use dirs_next::home_dir; + +#[derive(Clone, Debug)] +pub struct AppDirs { + pub cache_dir: PathBuf, + pub config_dir: PathBuf, + pub data_dir: PathBuf, + pub state_dir: PathBuf, +} + +#[derive(Clone, Debug)] +pub struct UserDirs { + pub desktop_dir: PathBuf, + pub document_dir: PathBuf, + pub download_dir: PathBuf, + pub music_dir: PathBuf, + pub picture_dir: PathBuf, + pub public_dir: PathBuf, + pub video_dir: PathBuf, +} + +fn is_absolute_path(path: impl AsRef) -> Option { + let path = path.as_ref(); + + if path.is_absolute() { + Some(path.to_path_buf()) + } else { + None + } +} + +impl AppDirs { + pub fn new(name: Option<&str>, use_xdg_on_macos: bool) -> Option { + if cfg!(target_os = "macos") && !use_xdg_on_macos { + if home_dir().is_some() { + let mut cache_dir = dirs_next::cache_dir().expect("home directory is set"); + let mut data_dir = dirs_next::data_dir().expect("home directory is set"); + + if let Some(name) = name { + cache_dir.push(&name); + data_dir.push(&name); + } + + let config_dir = data_dir.clone(); + let state_dir = data_dir.clone(); + + Some(AppDirs { + cache_dir, + config_dir, + data_dir, + state_dir, + }) + } else { + None + } + } else if cfg!(target_os = "windows") { + // TODO document why we need to check data_dir and data_local_dir + if let (Some(_home_dir), Some(data_dir), Some(data_local_dir)) = ( + home_dir(), + dirs_next::data_dir(), + dirs_next::data_local_dir(), + ) { + let mut cache_dir = data_local_dir.clone(); + let mut config_dir = data_dir.clone(); + let mut data_dir = data_local_dir.clone(); + + if let Some(name) = name { + cache_dir.push(&name); + config_dir.push(&name); + data_dir.push(&name); + } + + let state_dir = data_dir.clone(); + + Some(AppDirs { + cache_dir, + config_dir, + data_dir, + state_dir, + }) + } else { + None + } + } else if let Some(home_dir) = home_dir() { + let mut cache_dir = env::var_os("XDG_CACHE_HOME") + .and_then(is_absolute_path) + .unwrap_or_else(|| home_dir.join(".cache")); + let mut config_dir = env::var_os("XDG_CONFIG_HOME") + .and_then(is_absolute_path) + .unwrap_or_else(|| home_dir.join(".config")); + let mut data_dir = env::var_os("XDG_DATA_HOME") + .and_then(is_absolute_path) + .unwrap_or_else(|| home_dir.join(".local/share")); + let mut state_dir = env::var_os("XDG_STATE_HOME") + .and_then(is_absolute_path) + .unwrap_or_else(|| home_dir.join(".local/state")); + + if let Some(name) = name { + cache_dir.push(&name); + config_dir.push(&name); + data_dir.push(&name); + state_dir.push(&name); + } + + Some(AppDirs { + cache_dir, + config_dir, + data_dir, + state_dir, + }) + } else { + None + } + } +} + +impl UserDirs { + pub fn new() -> Option { + if let Some(home_dir) = home_dir() { + Some(UserDirs { + desktop_dir: dirs_next::desktop_dir().unwrap_or_else(|| home_dir.join("Desktop")), + document_dir: dirs_next::document_dir() + .unwrap_or_else(|| home_dir.join("Documents")), + download_dir: dirs_next::download_dir() + .unwrap_or_else(|| home_dir.join("Downloads")), + music_dir: dirs_next::audio_dir().unwrap_or_else(|| home_dir.join("Music")), + picture_dir: dirs_next::picture_dir().unwrap_or_else(|| home_dir.join("Pictures")), + public_dir: dirs_next::public_dir().unwrap_or_else(|| home_dir.join("Public")), + video_dir: dirs_next::video_dir().unwrap_or_else(|| { + if cfg!(target_os = "macos") { + home_dir.join("Movies") + } else { + home_dir.join("Videos") + } + }), + }) + } else { + None + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn test_xdg() { + let home_dir = home_dir().unwrap(); + let config_env = env::var_os("XDG_CONFIG_HOME"); + + env::set_var("XDG_CONFIG_HOME", ""); + let app_dirs = AppDirs::new(None, AppUI::CommandLine).unwrap(); + assert!(app_dirs.config_dir == home_dir.join(".config")); + + env::set_var("XDG_CONFIG_HOME", "/home/cjbassi/foo"); + let app_dirs = AppDirs::new(Some("bar"), AppUI::CommandLine).unwrap(); + assert!(app_dirs.config_dir == home_dir.join("/home/cjbassi/foo/bar")); + + if let Some(config_env) = config_env { + env::set_var("XDG_CONFIG_HOME", config_env); + } + } + + #[test] + fn test_config_dir() { + if cfg!(target_os = "macos") { + let home_dir = home_dir().unwrap(); + let app_dirs = AppDirs::new(Some("foo"), AppUI::Graphical).unwrap(); + assert_eq!( + app_dirs.config_dir, + home_dir + .join("Library") + .join("Application Support") + .join("foo"), + ); + test_xdg(); + } else if cfg!(target_os = "windows") { + let home_dir = home_dir().unwrap(); + let app_dirs = AppDirs::new(Some("foo"), AppUI::Graphical).unwrap(); + assert_eq!( + app_dirs.config_dir, + home_dir.join("AppData").join("Roaming").join("foo") + ); + } else { + test_xdg(); + } + } + + #[test] + fn test_music_dir() { + let music_dir = home_dir().unwrap().join("Music"); + let user_dirs = UserDirs::new().unwrap(); + assert!(user_dirs.music_dir == music_dir); + } +}