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