env_vars_config/lib.rs
1//! A simple lib for configuring your applications via environment variables
2
3#[doc(hidden)]
4pub extern crate log;
5
6/// Creates new mod with specified environment variables
7/// # Examples
8///
9/// ```
10/// use env_vars_config::env_vars_config;
11///
12/// env_vars_config! {
13/// SERVER_ADDRESS: String = "0.0.0.0:8080",
14/// WORKERS_COUNT: i32 = 32
15/// }
16///
17/// assert_eq!(config::SERVER_ADDRESS.as_str(), "0.0.0.0:8080");
18/// assert_eq!(config::WORKERS_COUNT.clone(), 32);
19/// ```
20/// # Panics
21///
22/// ```no_compile
23/// use env_vars_config::env_vars_config;
24///
25/// env_vars_config! {
26/// // incompatible type
27/// ENABLE_REGISTRATION: bool = "false"
28/// }
29/// ```
30#[macro_export]
31macro_rules! env_vars_config {
32 ( $( $name:ident: $type:tt = $default_value:expr ),* $(,)? ) => {
33 pub mod config {
34 use std::{
35 sync::LazyLock,
36 env,
37 any::type_name,
38 };
39
40 #[inline]
41 fn get_variable_type<T>(_: &T) -> &'static str {
42 type_name::<T>().split("::").last().unwrap()
43 }
44
45 $(
46 /// Our environment variable. Lazy-evaluated by default
47 pub static $name: LazyLock<$type> = LazyLock::new(|| {
48 let name = stringify!($name);
49
50 if let Ok(value) = env::var(name) {
51 if let Ok(value) = value.parse::<$type>() {
52 value
53 } else {
54 panic!(
55 "Invalid value type for the variable `{name}`! Expected type `{}`, got `{}`.",
56 stringify!($type),
57 get_variable_type(&value)
58 )
59 }
60 } else {
61 env_vars_config::log::warn!(
62 "Variable `{}` is missing in the env! Using default value `{}`",
63 name,
64 $default_value
65 );
66 <$type>::from($default_value)
67 }
68 });
69 )*
70
71 /// Inits all environment variables
72 pub fn init() {
73 $(
74 LazyLock::force(&$name);
75 )*
76 }
77 }
78 };
79}