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
use std::fmt;
/// Error produced when loading or parsing environment variables.
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum EnvLockError {
/// A required variable was absent from the environment (or the map).
#[non_exhaustive]
Missing {
variable: String,
/// Optional hint attached via [`EnvLockError::with_hint`].
hint: Option<String>,
},
/// A variable was present but its value could not be parsed into the target type.
#[non_exhaustive]
Parse {
variable: String,
found: String,
/// Description of what was expected (the `Display` output of the parse error).
expected: String,
/// Optional extra hint added via [`EnvLockError::with_hint`].
hint: Option<String>,
},
/// A `.env` file could not be loaded (feature `dotenv`).
#[non_exhaustive]
Dotenv {
path: String,
cause: String,
/// Optional hint attached via [`EnvLockError::with_hint`].
hint: Option<String>,
},
}
impl EnvLockError {
/// Create a `Missing` error for the given variable name.
#[must_use]
pub fn missing(variable: String) -> Self {
EnvLockError::Missing {
variable,
hint: None,
}
}
/// Create a `Parse` error, converting the parse failure to a string automatically.
pub fn parse_error<E: fmt::Display>(variable: String, found: String, err: E) -> Self {
EnvLockError::Parse {
variable,
found,
expected: err.to_string(),
hint: None,
}
}
/// Create a `Dotenv` error (feature `dotenv`).
#[must_use]
pub fn dotenv(path: String, cause: String) -> Self {
EnvLockError::Dotenv {
path,
cause,
hint: None,
}
}
/// Attach a hint to any error variant.
/// The hint is shown in `Display` output after the primary message.
#[must_use]
pub fn with_hint(mut self, hint: impl Into<String>) -> Self {
match &mut self {
EnvLockError::Missing { hint: h, .. }
| EnvLockError::Parse { hint: h, .. }
| EnvLockError::Dotenv { hint: h, .. } => {
*h = Some(hint.into());
}
}
self
}
}
impl fmt::Display for EnvLockError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
EnvLockError::Missing { variable, hint } => {
write!(f, "EnvLockError: missing required variable\n variable: {variable}\n hint: add {variable} to your environment or .env file")?;
if let Some(h) = hint {
write!(f, "\n hint: {h}")?;
}
Ok(())
}
EnvLockError::Parse {
variable,
found,
expected,
hint,
} => {
write!(f, "EnvLockError: failed to parse environment variable\n variable: {variable}\n found: \"{found}\"\n expected type: {expected}")?;
if let Some(h) = hint {
write!(f, "\n hint: {h}")?;
}
Ok(())
}
EnvLockError::Dotenv { path, cause, hint } => {
write!(
f,
"EnvLockError: failed to load .env file\n path: {path}\n cause: {cause}"
)?;
if let Some(h) = hint {
write!(f, "\n hint: {h}")?;
}
Ok(())
}
}
}
}
impl std::error::Error for EnvLockError {}