1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
//! This is a Rust library that aims to allow you to determine the locations of configuration, cache and data files for your application. Existing Rust libraries generally do not give you a choice in terms of which standards/conventions (Etcetera calls these ‘strategies’) they follow. Etcetera, on the other hand, gives you the choice. //! //! If you want to get started quickly, you can use the provided convenience functions that use the default strategies (as determined arbitrarily by yours truly) for each OS. //! //! This first example is for when you just want the path to a configuration, data or cache directory (this is called a ‘base strategy’): //! //! ``` //! use etcetera::base_strategy; //! use etcetera::base_strategy::BaseStrategy; //! //! let strategy = base_strategy::choose_base_strategy().unwrap(); //! //! let config_dir = strategy.config_dir(); //! let data_dir = strategy.data_dir(); //! let cache_dir = strategy.cache_dir(); //! ``` //! //! Here is an example where you provide Etcetera with some basic information about your application, and Etcetera will in turn give you a path that includes this information (this is called an ‘app strategy’). //! //! Let’s take an application created by Acme Corp with the name Frobnicator and the top-level domain of `.org` as an example. With Apple’s strategy, configuration files would be located in `~/Library/Preferences/org.acmecorp.Frobnicator/`. XDG would place these in `~/.config/frobnicator/`, on the other hand. Etcetera takes care of the distinctions. //! //! ``` //! use etcetera::app_strategy; //! use etcetera::app_strategy::AppStrategy; //! use etcetera::app_strategy::AppStrategyArgs; //! //! let strategy = app_strategy::choose_app_strategy(AppStrategyArgs { //! top_level_domain: "org".to_string(), //! author: "Acme Corp".to_string(), //! app_name: "Frobnicator".to_string(), //! }).unwrap(); //! //! let config_dir = strategy.config_dir(); //! let data_dir = strategy.data_dir(); //! let cache_dir = strategy.cache_dir(); //! ``` //! //! Say you were a hardened Unix veteran, and didn’t want to have any of this XDG nonsense, clutter in the home directory be damned! Instead of using `choose_app_strategy` or `choose_base_strategy`, you can pick a strategy yourself. Here’s an example using the [`Unix`](app_strategy/struct.Unix.html) strategy – see its documentation to see what kind of folder structures it produces: //! //! ``` //! use etcetera::app_strategy; //! use etcetera::app_strategy::AppStrategy; //! use etcetera::app_strategy::AppStrategyArgs; //! //! let strategy = app_strategy::Unix::new(AppStrategyArgs { //! top_level_domain: "com".to_string(), //! author: "Hardened Unix Veteran Who Likes Short Command Names".to_string(), //! app_name: "wry".to_string(), //! }).unwrap(); //! //! let config_dir = strategy.config_dir(); // produces ~/.wry/ //! // et cetera. //! ``` //! //! Oftentimes the location of a configuration, data or cache directory is needed solely to locate a single file inside of it. For this purpose, [`AppStrategy`](app_strategy/trait.AppStrategy.html) implements a couple of convenience methods for you: //! //! ``` //! use etcetera::app_strategy; //! use etcetera::app_strategy::AppStrategy; //! use etcetera::app_strategy::AppStrategyArgs; //! //! let strategy = app_strategy::choose_app_strategy(AppStrategyArgs { //! top_level_domain: "org".to_string(), //! author: "Acme Corp".to_string(), //! app_name: "Frobnicator".to_string(), //! }).unwrap(); //! //! // Path to configuration directory. //! let config_dir = strategy.config_dir(); //! //! // Path to config.toml inside the configuration directory. //! let config_file = strategy.config_file("config.toml"); //! //! assert_eq!(config_dir.join("config.toml"), config_file); //! ``` //! //! You aren’t limited to the built-in strategies, however – you can implement the relevant traits yourself. Please consider contributing these back, as the more preset strategies there are, the better. #![warn(missing_docs, rust_2018_idioms, missing_debug_implementations)] pub mod app_strategy; pub mod base_strategy; /// A convenience function that wraps the [`home_dir`](https://docs.rs/dirs/2/dirs/fn.home_dir.html) function from the [dirs](https://docs.rs/dirs) crate. pub fn home_dir() -> Result<std::path::PathBuf, HomeDirError> { dirs::home_dir().ok_or(HomeDirError) } /// This error occurs when the home directory cannot be located. #[derive(Debug, thiserror::Error)] #[error("could not locate home directory")] pub struct HomeDirError;