|
1 | 1 | use std::{convert::Infallible, env::VarError, num::ParseIntError, str::FromStr}; |
2 | 2 |
|
| 3 | +/// Details about an environment variable. This is used to generate |
| 4 | +/// documentation for the environment variables and by the [`FromEnv`] trait to |
| 5 | +/// check if necessary environment variables are present. |
| 6 | +#[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| 7 | +pub struct EnvItemInfo { |
| 8 | + /// The environment variable name. |
| 9 | + pub var: &'static str, |
| 10 | + /// A description of the environment variable function in the CFG. |
| 11 | + pub description: &'static str, |
| 12 | + /// Whether the environment variable is optional or not. |
| 13 | + pub optional: bool, |
| 14 | +} |
| 15 | + |
3 | 16 | /// Error type for loading from the environment. See the [`FromEnv`] trait for |
4 | 17 | /// more information. |
5 | 18 | #[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)] |
@@ -93,6 +106,33 @@ pub trait FromEnv: core::fmt::Debug + Sized + 'static { |
93 | 106 | /// Error type produced when loading from the environment. |
94 | 107 | type Error: core::error::Error; |
95 | 108 |
|
| 109 | + /// Get the required environment variable names for this type. |
| 110 | + /// |
| 111 | + /// ## Note |
| 112 | + /// |
| 113 | + /// This MUST include the environment variable names for all fields in the |
| 114 | + /// struct, including optional vars. |
| 115 | + fn inventory() -> Vec<&'static EnvItemInfo>; |
| 116 | + |
| 117 | + /// Get a list of missing environment variables. |
| 118 | + /// |
| 119 | + /// This will check all environment variables in the inventory, and return |
| 120 | + /// a list of those that are non-optional and missing. This is useful for |
| 121 | + /// reporting missing environment variables. |
| 122 | + fn check_inventory() -> Result<(), Vec<&'static EnvItemInfo>> { |
| 123 | + let mut missing = Vec::new(); |
| 124 | + for var in Self::inventory() { |
| 125 | + if std::env::var(var.var).is_err() && !var.optional { |
| 126 | + missing.push(var); |
| 127 | + } |
| 128 | + } |
| 129 | + if missing.is_empty() { |
| 130 | + Ok(()) |
| 131 | + } else { |
| 132 | + Err(missing) |
| 133 | + } |
| 134 | + } |
| 135 | + |
96 | 136 | /// Load from the environment. |
97 | 137 | fn from_env() -> Result<Self, FromEnvErr<Self::Error>>; |
98 | 138 | } |
|
0 commit comments