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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#![deny(missing_docs)]
#![doc(issue_tracker_base_url = "https://github.com/dariocurr/env-settings/issues")]
#![doc(
    html_logo_url = "https://raw.githubusercontent.com/dariocurr/env-settings/main/docs/logo.svg",
    html_favicon_url = "https://raw.githubusercontent.com/dariocurr/env-settings/main/docs/logo.ico"
)]

//! # Env Settings
//!
//! **Env Settings** is a Rust library that helps you to initialize structs using environment variables
//!
//! > This Rust library took inspiration from [`pydantic's BaseSettings`](https://docs.pydantic.dev/latest/usage/pydantic_settings/) Python class
//!
//! ## Installation
//!
//! ```bash
//! cargo add env-settings env-settings-derive env-settings-utils
//! ```
//!
//! ## Usage
//!
//! When you add the `EnvSettings` derive to a `struct`, two public methods are added to it
//!
//! ```ignore
//! fn from_env(...) -> env_settings_utils::EnvSettingsResult<Self>
//! ```
//!
//! It creates a new instance using just the environment variables. Skipped fields must be passed.
//| If something fails, it returns an `env_settings_utils::EnvSettingsError` error
//!
//! ```ignore
//! fn new(...) -> env_settings_utils::EnvSettingsResult<Self>
//! ```
//!
//! It creates a new instance using a combination of environment variables and parameters.
//! More in detail, every field that can be initialized by the environment variables can be passed as
//! parameter wrapped in an `Option` object. Then if the parameter is `Some`, it is used,
//! otherwise the value is recoved from the environment variables. Skipped fields must be passed.
//! If something fails, it returns an `env_settings_utils::EnvSettingsError` error
//!
//! ### Basic
//!
//! ```rust
//! // `export name=paolo` in shell or
//! std::env::set_var("name", "paolo");
//! // `export favourite_number=42` in shell or
//! std::env::set_var("favourite_number", "42");
//!
//!
//! use env_settings_derive::EnvSettings;
//!
//! // `delay` is necessary because environment variables are set at run time
//! #[derive(EnvSettings)]
//! #[env_settings(delay)]
//! struct MyStruct {
//!     name: String,
//!
//!     favourite_number: u8,
//! }
//!
//! let my_struct = MyStruct::from_env().unwrap();
//! assert_eq!(my_struct.name, "paolo".to_string());
//! assert_eq!(my_struct.favourite_number, 42);
//!
//! let name = "luca";
//! let my_struct = MyStruct::new(Some(name.to_string()), None).unwrap();
//! assert_eq!(my_struct.name, name);
//! assert_eq!(my_struct.favourite_number, 42);
//! ```
//!
//! ### Advanced
//!
//! ```rust
//! use std::io::prelude::Write;
//!
//! // `echo "MY_STRUCT_FAVOURITE_NUMBER=42\n" > .env` in shell or
//! let mut env_file = std::fs::File::create(".env").unwrap();
//! env_file.write_all("MY_STRUCT_FAVOURITE_NUMBER=42\n".as_bytes()).unwrap();
//! // `export MY_BIRTH_DATE=01/01/1970` in shell or
//! std::env::set_var("MY_BIRTH_DATE", "01/01/1970");
//!
//!
//! use env_settings_derive::EnvSettings;
//!
//! // `delay` is necessary because environment variables are set at run time
//! #[derive(EnvSettings)]
//! #[env_settings(case_insensitive, delay, file_path = ".env", prefix="MY_STRUCT_")]
//! struct MyStruct {
//!     #[env_settings(default = "paolo")]
//!     name: String,
//!
//!     favourite_number: u8,
//!
//!     #[env_settings(variable = "MY_BIRTH_DATE")]
//!     birth_date: String,
//!
//!     birth_place: Option<String>,
//!
//!     #[env_settings(skip)]
//!     friends: Vec<String>,
//! }
//!
//! let friends = vec!["luca".to_string()];
//! let my_struct = MyStruct::from_env(friends.clone()).unwrap();
//! assert_eq!(my_struct.name, "paolo".to_string());
//! assert_eq!(my_struct.favourite_number, 42);
//! assert_eq!(my_struct.birth_date, "01/01/1970");
//! assert_eq!(my_struct.birth_place, None);
//! assert_eq!(my_struct.friends, friends);
//!
//! let name = "luca";
//! let my_struct = MyStruct::new(
//!     Some(name.to_string()),
//!     None,
//!     None,
//!     Some("london".to_string()),
//!     friends.clone(),
//! ).unwrap();
//! assert_eq!(my_struct.name, name);
//! assert_eq!(my_struct.favourite_number, 42);
//! assert_eq!(my_struct.birth_date, "01/01/1970");
//! assert_eq!(my_struct.birth_place, Some("london".to_string()));
//! assert_eq!(my_struct.friends, friends);
//! ```
//!
//! ### Parameters
//!
//! #### Struct
//!
//! The current supported parameters for the structs are:
//!
//! -   `case_insensitive`: whether the environment variables matching should be case insensitive. By default, matching is case sensitive.
//! -   `delay`: whether to delay the lookup for environment variables from compilation time to run time. By default the lookup is performed at compilation time
//! -   `file_path`: the file path to read to add some environment variables (e.g. `.env`). By default, it is not set
//! -   `prefix`: the prefix to add to the name of the struct fields before matching the environment variables. By default, it is not set
//!
//! #### Field
//!
//! The current supported parameters for the fields are:
//!
//! -   `default`: the default value to use if the environment variable is not found. By default, it is not set
//! -   `skip`: whether to skip the parsing of the environment variable. It is necessary if the type specified does not implement `std::str::FromStr`
//! -   `variable`: the environment variable to use for the lookup. By default, the name of the field
//!
//! ### Variables resolution hierarchy
//!
//! 1. Arguments passed to the `new` method (if using `new`).
//! 2. Environment variables
//! 3. Variables loaded from a file (e.g. `.env`)
//! 4. Default values
//!

/// The trait to add to the derive
pub trait EnvSettings {}