dotenv/
lib.rs

1//! This crate provides a configuration loader in the style of the [ruby dotenv
2//! gem](https://github.com/bkeepers/dotenv). This library is meant to be used
3//! on development or testing environments in which setting environment
4//! variables is not practical. It loads environment variables from a .env
5//! file, if available, and mashes those with the actual environment variables
6//! provided by the operating system.
7
8mod parse;
9mod errors;
10mod iter;
11mod find;
12
13use std::env::{self, Vars};
14use std::ffi::OsStr;
15use std::fs::File;
16use std::path::{Path, PathBuf};
17use std::sync::{Once, ONCE_INIT};
18
19pub use crate::errors::*;
20use crate::iter::Iter;
21use crate::find::Finder;
22
23static START: Once = ONCE_INIT;
24
25/// After loading the dotenv file, fetches the environment variable key from the current process.
26///
27/// The returned result is Ok(s) if the environment variable is present and is valid unicode. If the
28/// environment variable is not present, or it is not valid unicode, then Err will be returned.
29///
30/// Examples:
31///
32/// ```no_run
33///
34/// use dotenv;
35///
36/// let key = "FOO";
37/// let value= dotenv::var(key).unwrap();
38/// ```
39pub fn var<K: AsRef<OsStr>>(key: K) -> Result<String> {
40    START.call_once(|| {
41        dotenv().ok();
42    });
43    env::var(key).map_err(Error::EnvVar)
44}
45
46/// After loading the dotenv file, returns an iterator of (variable, value) pairs of strings,
47/// for all the environment variables of the current process.
48///
49/// The returned iterator contains a snapshot of the process's environment variables at the
50/// time of this invocation, modifications to environment variables afterwards will not be
51/// reflected in the returned iterator.
52/// 
53/// Examples:
54///
55/// ```no_run
56///
57/// use dotenv;
58/// use std::io;
59///
60/// let result: Vec<(String, String)> = dotenv::vars().collect();
61/// ```
62pub fn vars() -> Vars {
63    START.call_once(|| {
64        dotenv().ok();
65    });
66    env::vars()
67}
68
69/// Loads the file at the specified absolute path.
70///
71/// Examples
72///
73/// ```
74/// use dotenv;
75/// use std::env;
76/// use std::path::{Path};
77///
78/// let my_path = env::home_dir().and_then(|a| Some(a.join("/.env"))).unwrap();
79/// dotenv::from_path(my_path.as_path());
80/// ```
81pub fn from_path<P: AsRef<Path>>(path: P) -> Result<()> {
82    let iter = Iter::new(File::open(path).map_err(Error::Io)?);
83    iter.load()
84}
85
86/// Like `from_path`, but returns an iterator over variables instead of loading into environment.
87///
88/// Examples
89///
90/// ```no_run
91/// use dotenv;
92/// use std::env;
93/// use std::path::{Path};
94///
95/// let my_path = env::home_dir().and_then(|a| Some(a.join("/.env"))).unwrap();
96/// let iter = dotenv::from_path_iter(my_path.as_path()).unwrap();
97///
98/// for item in iter {
99///   let (key, val) = item.unwrap();
100///   println!("{}={}", key, val);
101/// }
102/// ```
103#[deprecated(since = "0.14.1", note = "please use `from_path` in conjunction with `var` instead")]
104pub fn from_path_iter<P: AsRef<Path>>(path: P) -> Result<Iter<File>> {
105    Ok(Iter::new(File::open(path).map_err(Error::Io)?))
106}
107
108/// Loads the specified file from the environment's current directory or its parents in sequence.
109///
110/// # Examples
111/// ```
112/// use dotenv;
113/// dotenv::from_filename("custom.env").ok();
114/// ```
115///
116/// It is also possible to do the following, but it is equivalent to using `dotenv::dotenv()`,
117/// which is preferred.
118///
119/// ```
120/// use dotenv;
121/// dotenv::from_filename(".env").ok();
122/// ```
123pub fn from_filename<P: AsRef<Path>>(filename: P) -> Result<PathBuf> {
124    let (path, iter) = Finder::new().filename(filename.as_ref()).find()?;
125    iter.load()?;
126    Ok(path)
127}
128
129/// Like `from_filename`, but returns an iterator over variables instead of loading into environment.
130///
131/// # Examples
132/// ```
133/// use dotenv;
134/// dotenv::from_filename("custom.env").ok();
135/// ```
136///
137/// It is also possible to do the following, but it is equivalent to using `dotenv::dotenv()`,
138/// which is preferred.
139///
140/// ```no_run
141/// use dotenv;
142/// let iter = dotenv::from_filename_iter(".env").unwrap();
143///
144/// for item in iter {
145///   let (key, val) = item.unwrap();
146///   println!("{}={}", key, val);
147/// }
148/// ```
149#[deprecated(since = "0.14.1", note = "please use `from_path` in conjunction with `var` instead")]
150pub fn from_filename_iter<P: AsRef<Path>>(filename: P) -> Result<Iter<File>> {
151    let (_, iter) = Finder::new().filename(filename.as_ref()).find()?;
152    Ok(iter)
153}
154
155/// This is usually what you want.
156/// It loads the .env file located in the environment's current directory or its parents in sequence.
157///
158/// # Examples
159/// ```
160/// use dotenv;
161/// dotenv::dotenv().ok();
162/// ```
163pub fn dotenv() -> Result<PathBuf> {
164    let (path, iter) = Finder::new().find()?;
165    iter.load()?;
166    Ok(path)
167}
168
169/// Like `dotenv`, but returns an iterator over variables instead of loading into environment.
170///
171/// # Examples
172/// ```no_run
173/// use dotenv;
174///
175/// for item in dotenv::dotenv_iter().unwrap() {
176///   let (key, val) = item.unwrap();
177///   println!("{}={}", key, val);
178/// }
179/// ```
180#[deprecated(since = "0.14.1", note = "please use `from_path` in conjunction with `var` instead")]
181pub fn dotenv_iter() -> Result<iter::Iter<File>> {
182    let (_, iter) = Finder::new().find()?;
183    Ok(iter)
184}