Coverage Report

Created: 2025-10-31 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/dotenvy-0.15.7/src/lib.rs
Line
Count
Source
1
//! [`dotenv`]: https://crates.io/crates/dotenv
2
//! A well-maintained fork of the [`dotenv`] crate
3
//!
4
//! This library loads environment variables from a *.env* file. This is convenient for dev environments.
5
6
mod errors;
7
mod find;
8
mod iter;
9
mod parse;
10
11
use std::env::{self, Vars};
12
use std::ffi::OsStr;
13
use std::fs::File;
14
use std::io;
15
use std::path::{Path, PathBuf};
16
use std::sync::Once;
17
18
pub use crate::errors::*;
19
use crate::find::Finder;
20
pub use crate::iter::Iter;
21
22
static START: Once = Once::new();
23
24
/// Gets the value for an environment variable.
25
///
26
/// The value is `Ok(s)` if the environment variable is present and valid unicode.
27
///
28
/// Note: this function gets values from any visible environment variable key,
29
/// regardless of whether a *.env* file was loaded.
30
///
31
/// # Examples:
32
///
33
/// ```no_run
34
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
35
/// let value = dotenvy::var("HOME")?;
36
/// println!("{}", value);  // prints `/home/foo`
37
/// #     Ok(())
38
/// # }
39
/// ```
40
0
pub fn var<K: AsRef<OsStr>>(key: K) -> Result<String> {
41
0
    START.call_once(|| {
42
0
        dotenv().ok();
43
0
    });
44
0
    env::var(key).map_err(Error::EnvVar)
45
0
}
46
47
/// Returns an iterator of `(key, value)` pairs for all environment variables of the current process.
48
/// The returned iterator contains a snapshot of the process's environment variables at the time of invocation. Modifications to environment variables afterwards will not be reflected.
49
///
50
/// # Examples:
51
///
52
/// ```no_run
53
/// use std::io;
54
///
55
/// let result: Vec<(String, String)> = dotenvy::vars().collect();
56
/// ```
57
0
pub fn vars() -> Vars {
58
0
    START.call_once(|| {
59
0
        dotenv().ok();
60
0
    });
61
0
    env::vars()
62
0
}
63
64
/// Loads environment variables from the specified path.
65
///
66
/// If variables with the same names already exist in the environment, then their values will be
67
/// preserved.
68
///
69
/// Where multiple declarations for the same environment variable exist in your *.env*
70
/// file, the *first one* is applied.
71
///
72
/// If you wish to ensure all variables are loaded from your *.env* file, ignoring variables
73
/// already existing in the environment, then use [`from_path_override`] instead.
74
///
75
/// # Examples
76
///
77
/// ```no_run
78
/// use std::path::Path;
79
///
80
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
81
/// dotenvy::from_path(Path::new("path/to/.env"))?;
82
/// #     Ok(())
83
/// # }
84
/// ```
85
0
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<()> {
86
0
    let iter = Iter::new(File::open(path).map_err(Error::Io)?);
87
0
    iter.load()
88
0
}
89
90
/// Loads environment variables from the specified path,
91
/// overriding existing environment variables.
92
///
93
/// Where multiple declarations for the same environment variable exist in your *.env* file, the
94
/// *last one* is applied.
95
///
96
/// If you want the existing environment to take precedence,
97
/// or if you want to be able to override environment variables on the command line,
98
/// then use [`from_path`] instead.
99
///
100
/// # Examples
101
///
102
/// ```no_run
103
/// use std::path::Path;
104
///
105
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
106
/// dotenvy::from_path_override(Path::new("path/to/.env"))?;
107
/// #     Ok(())
108
/// # }
109
/// ```
110
0
pub fn from_path_override<P: AsRef<Path>>(path: P) -> Result<()> {
111
0
    let iter = Iter::new(File::open(path).map_err(Error::Io)?);
112
0
    iter.load_override()
113
0
}
114
115
/// Returns an iterator over environment variables from the specified path.
116
///
117
/// # Examples
118
///
119
/// ```no_run
120
/// use std::path::Path;
121
///
122
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
123
/// for item in dotenvy::from_path_iter(Path::new("path/to/.env"))? {
124
///   let (key, val) = item?;
125
///   println!("{}={}", key, val);
126
/// }
127
/// #     Ok(())
128
/// # }
129
/// ```
130
0
pub fn from_path_iter<P: AsRef<Path>>(path: P) -> Result<Iter<File>> {
131
0
    Ok(Iter::new(File::open(path).map_err(Error::Io)?))
132
0
}
133
134
/// Loads environment variables from the specified file.
135
///
136
/// If variables with the same names already exist in the environment, then their values will be
137
/// preserved.
138
///
139
/// Where multiple declarations for the same environment variable exist in your *.env*
140
/// file, the *first one* is applied.
141
///
142
/// If you wish to ensure all variables are loaded from your *.env* file, ignoring variables
143
/// already existing in the environment, then use [`from_filename_override`] instead.
144
///
145
/// # Examples
146
/// ```no_run
147
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
148
/// dotenvy::from_filename("custom.env")?;
149
/// #     Ok(())
150
/// # }
151
/// ```
152
///
153
/// It is also possible to load from a typical *.env* file like so. However, using [`dotenv`] is preferred.
154
///
155
/// ```
156
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
157
/// dotenvy::from_filename(".env")?;
158
/// #     Ok(())
159
/// # }
160
/// ```
161
0
pub fn from_filename<P: AsRef<Path>>(filename: P) -> Result<PathBuf> {
162
0
    let (path, iter) = Finder::new().filename(filename.as_ref()).find()?;
163
0
    iter.load()?;
164
0
    Ok(path)
165
0
}
166
167
/// Loads environment variables from the specified file,
168
/// overriding existing environment variables.
169
///
170
/// Where multiple declarations for the same environment variable exist in your *.env* file, the
171
/// *last one* is applied.
172
///
173
/// If you want the existing environment to take precedence,
174
/// or if you want to be able to override environment variables on the command line,
175
/// then use [`from_filename`] instead.
176
///
177
/// # Examples
178
/// ```no_run
179
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
180
/// dotenvy::from_filename_override("custom.env")?;
181
/// #     Ok(())
182
/// # }
183
/// ```
184
///
185
/// It is also possible to load from a typical *.env* file like so. However, using [`dotenv_override`] is preferred.
186
///
187
/// ```
188
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
189
/// dotenvy::from_filename_override(".env")?;
190
/// #     Ok(())
191
/// # }
192
/// ```
193
0
pub fn from_filename_override<P: AsRef<Path>>(filename: P) -> Result<PathBuf> {
194
0
    let (path, iter) = Finder::new().filename(filename.as_ref()).find()?;
195
0
    iter.load_override()?;
196
0
    Ok(path)
197
0
}
198
199
///  Returns an iterator over environment variables from the specified file.
200
///
201
/// # Examples
202
///
203
/// ```no_run
204
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
205
/// for item in dotenvy::from_filename_iter("custom.env")? {
206
///     let (key, val) = item?;
207
///     println!("{}={}", key, val);
208
/// }
209
/// #     Ok(())
210
/// # }
211
/// ```
212
213
0
pub fn from_filename_iter<P: AsRef<Path>>(filename: P) -> Result<Iter<File>> {
214
0
    let (_, iter) = Finder::new().filename(filename.as_ref()).find()?;
215
0
    Ok(iter)
216
0
}
217
218
/// Loads environment variables from [`io::Read`](std::io::Read).
219
///
220
/// This is useful for loading environment variables from IPC or the network.
221
///
222
/// If variables with the same names already exist in the environment, then their values will be
223
/// preserved.
224
///
225
/// Where multiple declarations for the same environment variable exist in your `reader`,
226
/// the *first one* is applied.
227
///
228
/// If you wish to ensure all variables are loaded from your `reader`, ignoring variables
229
/// already existing in the environment, then use [`from_read_override`] instead.
230
///
231
/// For regular files, use [`from_path`] or [`from_filename`].
232
///
233
/// # Examples
234
///
235
/// ```no_run
236
/// # #![cfg(unix)]
237
/// use std::io::Read;
238
/// use std::os::unix::net::UnixStream;
239
///
240
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
241
/// let mut stream = UnixStream::connect("/some/socket")?;
242
/// dotenvy::from_read(stream)?;
243
/// #     Ok(())
244
/// # }
245
/// ```
246
0
pub fn from_read<R: io::Read>(reader: R) -> Result<()> {
247
0
    let iter = Iter::new(reader);
248
0
    iter.load()?;
249
0
    Ok(())
250
0
}
251
252
/// Loads environment variables from [`io::Read`](std::io::Read),
253
/// overriding existing environment variables.
254
///
255
/// This is useful for loading environment variables from IPC or the network.
256
///
257
/// Where multiple declarations for the same environment variable exist in your `reader`, the
258
/// *last one* is applied.
259
///
260
/// If you want the existing environment to take precedence,
261
/// or if you want to be able to override environment variables on the command line,
262
/// then use [`from_read`] instead.
263
///
264
/// For regular files, use [`from_path_override`] or [`from_filename_override`].
265
///
266
/// # Examples
267
/// ```no_run
268
/// # #![cfg(unix)]
269
/// use std::io::Read;
270
/// use std::os::unix::net::UnixStream;
271
///
272
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
273
/// let mut stream = UnixStream::connect("/some/socket")?;
274
/// dotenvy::from_read_override(stream)?;
275
/// #     Ok(())
276
/// # }
277
/// ```
278
0
pub fn from_read_override<R: io::Read>(reader: R) -> Result<()> {
279
0
    let iter = Iter::new(reader);
280
0
    iter.load_override()?;
281
0
    Ok(())
282
0
}
283
284
/// Returns an iterator over environment variables from [`io::Read`](std::io::Read).
285
///
286
/// # Examples
287
///
288
/// ```no_run
289
/// # #![cfg(unix)]
290
/// use std::io::Read;
291
/// use std::os::unix::net::UnixStream;
292
///
293
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
294
/// let mut stream = UnixStream::connect("/some/socket")?;
295
///
296
/// for item in dotenvy::from_read_iter(stream) {
297
///     let (key, val) = item?;
298
///     println!("{}={}", key, val);
299
/// }
300
/// #     Ok(())
301
/// # }
302
/// ```
303
0
pub fn from_read_iter<R: io::Read>(reader: R) -> Iter<R> {
304
0
    Iter::new(reader)
305
0
}
306
307
/// Loads the *.env* file from the current directory or parents. This is typically what you want.
308
///
309
/// If variables with the same names already exist in the environment, then their values will be
310
/// preserved.
311
///
312
/// Where multiple declarations for the same environment variable exist in your *.env*
313
/// file, the *first one* is applied.
314
///
315
/// If you wish to ensure all variables are loaded from your *.env* file, ignoring variables
316
/// already existing in the environment, then use [`dotenv_override`] instead.
317
///
318
/// An error will be returned if the file is not found.
319
///
320
/// # Examples
321
///
322
/// ```
323
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
324
/// dotenvy::dotenv()?;
325
/// #     Ok(())
326
/// # }
327
/// ```
328
1.56k
pub fn dotenv() -> Result<PathBuf> {
329
1.56k
    let (path, iter) = Finder::new().find()?;
330
0
    iter.load()?;
331
0
    Ok(path)
332
1.56k
}
333
334
/// Loads all variables found in the `reader` into the environment,
335
/// overriding any existing environment variables of the same name.
336
///
337
/// Where multiple declarations for the same environment variable exist in your *.env* file, the
338
/// *last one* is applied.
339
///
340
/// If you want the existing environment to take precedence,
341
/// or if you want to be able to override environment variables on the command line,
342
/// then use [`dotenv`] instead.
343
///
344
/// # Examples
345
/// ```
346
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
347
/// dotenvy::dotenv_override()?;
348
/// #     Ok(())
349
/// # }
350
/// ```
351
0
pub fn dotenv_override() -> Result<PathBuf> {
352
0
    let (path, iter) = Finder::new().find()?;
353
0
    iter.load_override()?;
354
0
    Ok(path)
355
0
}
356
357
/// Returns an iterator over environment variables.
358
///
359
/// # Examples
360
///
361
/// ```
362
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
363
/// for item in dotenvy::dotenv_iter()? {
364
///     let (key, val) = item?;
365
///     println!("{}={}", key, val);
366
/// }
367
/// #     Ok(())
368
/// # }
369
/// ```
370
0
pub fn dotenv_iter() -> Result<iter::Iter<File>> {
371
0
    let (_, iter) = Finder::new().find()?;
372
0
    Ok(iter)
373
0
}