env_settings/lib.rs
1#![deny(missing_docs)]
2#![doc(issue_tracker_base_url = "https://github.com/dariocurr/env-settings/issues")]
3#![doc(
4 html_logo_url = "https://raw.githubusercontent.com/dariocurr/env-settings/main/docs/logo.svg",
5 html_favicon_url = "https://raw.githubusercontent.com/dariocurr/env-settings/main/docs/logo.ico"
6)]
7
8//! # Env Settings
9//!
10//! **Env Settings** is a Rust library that helps you to initialize structs using environment variables
11//!
12//! > This Rust library took inspiration from [`pydantic's BaseSettings`](https://docs.pydantic.dev/latest/usage/pydantic_settings/) Python class
13//!
14//! ## Installation
15//!
16//! ```bash
17//! cargo add env-settings env-settings-derive env-settings-utils
18//! ```
19//!
20//! ## Usage
21//!
22//! When you add the `EnvSettings` derive to a `struct`, two public methods are added to it
23//!
24//! ```ignore
25//! fn from_env(...) -> env_settings_utils::EnvSettingsResult<Self>
26//! ```
27//!
28//! It creates a new instance using just the environment variables. Skipped fields must be passed.
29//| If something fails, it returns an `env_settings_utils::EnvSettingsError` error
30//!
31//! ```ignore
32//! fn new(...) -> env_settings_utils::EnvSettingsResult<Self>
33//! ```
34//!
35//! It creates a new instance using a combination of environment variables and parameters.
36//! More in detail, every field that can be initialized by the environment variables can be passed as
37//! parameter wrapped in an `Option` object. Then if the parameter is `Some`, it is used,
38//! otherwise the value is recoved from the environment variables. Skipped fields must be passed.
39//! If something fails, it returns an `env_settings_utils::EnvSettingsError` error
40//!
41//! ### Basic
42//!
43//! ```rust
44//! // `export name=paolo` in shell or
45//! unsafe {
46//! std::env::set_var("name", "paolo");
47//! }
48//! // `export favourite_number=42` in shell or
49//! unsafe {
50//! std::env::set_var("favourite_number", "42");
51//! }
52//!
53//!
54//! use env_settings_derive::EnvSettings;
55//!
56//! // `delay` is necessary because environment variables are set at run time
57//! #[derive(EnvSettings)]
58//! #[env_settings(delay)]
59//! struct MyStruct {
60//! name: String,
61//!
62//! favourite_number: u8,
63//! }
64//!
65//! let my_struct = MyStruct::from_env().unwrap();
66//! assert_eq!(my_struct.name, "paolo".to_string());
67//! assert_eq!(my_struct.favourite_number, 42);
68//!
69//! let name = "luca";
70//! let my_struct = MyStruct::new(Some(name.to_string()), None).unwrap();
71//! assert_eq!(my_struct.name, name);
72//! assert_eq!(my_struct.favourite_number, 42);
73//! ```
74//!
75//! ### Advanced
76//!
77//! ```rust
78//! use std::io::prelude::Write;
79//!
80//! // `echo "MY_STRUCT_FAVOURITE_NUMBER=42\n" > .env` in shell or
81//! let mut env_file = std::fs::File::create(".env").unwrap();
82//! env_file.write_all("MY_STRUCT_FAVOURITE_NUMBER=42\n".as_bytes()).unwrap();
83//! // `export MY_BIRTH_DATE=01/01/1970` in shell or
84//! unsafe {
85//! std::env::set_var("MY_BIRTH_DATE", "01/01/1970");
86//! }
87//!
88//!
89//! use env_settings_derive::EnvSettings;
90//!
91//! // `delay` is necessary because environment variables are set at run time
92//! #[derive(EnvSettings)]
93//! #[env_settings(case_insensitive, delay, file_path = ".env", prefix="MY_STRUCT_")]
94//! struct MyStruct {
95//! #[env_settings(default = "paolo")]
96//! name: String,
97//!
98//! favourite_number: u8,
99//!
100//! #[env_settings(variable = "MY_BIRTH_DATE")]
101//! birth_date: String,
102//!
103//! birth_place: Option<String>,
104//!
105//! #[env_settings(skip)]
106//! friends: Vec<String>,
107//! }
108//!
109//! let friends = vec!["luca".to_string()];
110//! let my_struct = MyStruct::from_env(friends.clone()).unwrap();
111//! assert_eq!(my_struct.name, "paolo".to_string());
112//! assert_eq!(my_struct.favourite_number, 42);
113//! assert_eq!(my_struct.birth_date, "01/01/1970");
114//! assert_eq!(my_struct.birth_place, None);
115//! assert_eq!(my_struct.friends, friends);
116//!
117//! let name = "luca";
118//! let my_struct = MyStruct::new(
119//! Some(name.to_string()),
120//! None,
121//! None,
122//! Some("london".to_string()),
123//! friends.clone(),
124//! ).unwrap();
125//! assert_eq!(my_struct.name, name);
126//! assert_eq!(my_struct.favourite_number, 42);
127//! assert_eq!(my_struct.birth_date, "01/01/1970");
128//! assert_eq!(my_struct.birth_place, Some("london".to_string()));
129//! assert_eq!(my_struct.friends, friends);
130//! ```
131//!
132//! ### Parameters
133//!
134//! #### Struct
135//!
136//! The current supported parameters for the structs are:
137//!
138//! - `case_insensitive`: whether the environment variables matching should be case insensitive. By default, matching is case sensitive.
139//! - `delay`: whether to delay the lookup for environment variables from compilation time to run time. By default the lookup is performed at compilation time
140//! - `file_path`: the file path to read to add some environment variables (e.g. `.env`). By default, it is not set
141//! - `prefix`: the prefix to add to the name of the struct fields before matching the environment variables. By default, it is not set
142//!
143//! #### Field
144//!
145//! The current supported parameters for the fields are:
146//!
147//! - `default`: the default value to use if the environment variable is not found. By default, it is not set
148//! - `skip`: whether to skip the parsing of the environment variable. It is necessary if the type specified does not implement `std::str::FromStr`
149//! - `variable`: the environment variable to use for the lookup. By default, the name of the field
150//!
151//! ### Variables resolution hierarchy
152//!
153//! 1. Arguments passed to the `new` method (if using `new`).
154//! 2. Environment variables
155//! 3. Variables loaded from a file (e.g. `.env`)
156//! 4. Default values
157//!
158
159/// The trait to add to the derive
160pub trait EnvSettings {}