configurable/
lib.rs

1//! This crate provides a set of functions for loading/saving structs to toml files in
2//! OS-accurate locations
3//!
4//! # A normal configuration (e.g. saving something to a toml file in CONFIG_DIR)
5//! ```
6//! use configurable::{Configurable, Config, Data, Error, LoadState};
7//! use serde::{Serialize, Deserialize};
8//!
9//! #[derive(Serialize, Deserialize)]
10//! struct MyConfiguration {
11//!     name: String,
12//!     attempts: u32,
13//!     force: bool,
14//! }
15//!
16//! impl Default for MyConfiguration {
17//!     fn default() -> Self {
18//!         Self {
19//!             name: "Foobar".into(),
20//!             attempts: 3,
21//!             force: false,
22//!         }
23//!     }
24//! }
25//!
26//! impl Config for MyConfiguration {}
27//!
28//! impl Configurable for MyConfiguration {
29//!     const ORGANIZATION: &'static str = "museun";
30//!     const APPLICATION: &'static str = "foobar";
31//!     const NAME: &'static str = "config.toml";
32//!
33//!     fn ensure_dir() -> Result<std::path::PathBuf, Error> {
34//!         <Self as Config>::ensure_dir()
35//!     }
36//! }
37//! ```
38//!
39//! # A 'data' configuration (e.g. saving something to a json file in the DATA_DIR)
40//! ```
41//! use configurable::{Configurable, Config, Data, Error, LoadState};
42//! use serde::{Serialize, Deserialize};
43//!
44//! #[derive(Default, Serialize, Deserialize)]
45//! struct MyData {
46//!     #[serde(flatten)]
47//!     data: std::collections::HashMap<String, String>
48//! }
49//!
50//! impl Data for MyData {}
51//!
52//! impl Configurable for MyData {
53//!     const ORGANIZATION: &'static str = "museun";
54//!     const APPLICATION: &'static str = "foobar";
55//!     const NAME: &'static str = "data.json";
56//!
57//!     fn ensure_dir() -> Result<std::path::PathBuf, Error> {
58//!         <Self as Data>::ensure_dir()
59//!     }
60//! }
61//! ```
62//!
63//! # Loading the data
64//! ```norun
65//! fn load_my_stuff() -> Something {
66//!     use configurable::Configuable;
67//!     // this tries to load the configuration ot creates a default instance of it
68//!     match match Something::load_or_default() {
69//!         Ok(data) => data,
70//!         Err(err) => {
71//!             eprintln!("cannot load configuration: {}", err);
72//!             std::process::exit(1)
73//!         }
74//!     } {
75//!         // it was successfully loaded
76//!         configurable::LoadState::Loaded(this) => this,
77//!         // it was defaulted
78//!         configurable::LoadState::Default(this) => {
79//!             eprintln!(
80//!                 "a default configuration was created at: {}",
81//!                 Something::path().unwrap().display()
82//!             );
83//!             std::process::exit(1)
84//!         }
85//!     }
86//! }
87//! ```
88
89/// State of the instance from `load_or_default`
90#[derive(Debug)]
91pub enum LoadState<T> {
92    /// When the instance was defaulted
93    Default(T),
94    /// When the instance was loaded
95    Loaded(T),
96}
97
98mod configurable;
99#[doc(inline)]
100pub use self::configurable::{Config, Configurable, Data};
101
102mod env;
103#[doc(inline)]
104pub use self::env::Env;
105
106mod error;
107#[doc(inline)]
108pub use self::error::Error;