Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(docs): Handle errors, rather than using unwrap, in examples #52

Merged
merged 3 commits into from Dec 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -15,6 +15,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

- Minimum Supported Rust Version is now 1.56.1
- Removed internal `dotenv_codegen_impl` crate and `proc_macro_hack` dependency
- Improved examples by handling errors, rather than using `unwrap`. ([PR #52](https://github.com/allan2/dotenvy/pull/52) by [LeoniePhiline](https://github.com/LeoniePhiline))

## [0.15.6] - 2022-10-17

Expand Down
1 change: 0 additions & 1 deletion dotenv/Cargo.toml
Expand Up @@ -29,7 +29,6 @@ clap = { version = "3.2", optional = true }

[dev-dependencies]
tempfile = "3.3.0"
dirs = "4.0"

[features]
cli = ["clap"]
15 changes: 9 additions & 6 deletions dotenv/README.md
Expand Up @@ -22,17 +22,20 @@ This library loads environment variables from a _.env_ file. This is convenient

### Loading at runtime

```rs
use dotenvy::dotenv;
```rust
use std::env;
use std::error::Error;

fn main() {
// load environment variables from .env file
dotenv().expect(".env file not found");
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line notably produced misleading error messages, claiming the file was not found even in cases where it actually contained invalid variable declarations.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point

fn main() -> Result<(), Box<dyn Error>> {
// Load environment variables from .env file.
// Fails if .env file not found, not readable or invalid.
dotenvy::dotenv()?;

for (key, value) in env::vars() {
println!("{key}: {value}");
}

Ok(())
}
```

Expand All @@ -59,13 +62,13 @@ This fork intends to serve as the development home for the dotenv implementation

This repo fixes:

- home directory works correctly (no longer using the deprecated `std::env::home_dir`)
- more helpful errors for `dotenv!` ([dotenv-rs/dotenv #57](https://github.com/dotenv-rs/dotenv/pull/57))

It also adds:

- multiline support for environment variable values
- `io::Read` support via [`from_read`](https://docs.rs/dotenvy/latest/dotenvy/fn.from_read.html) and [`from_read_iter`](https://docs.rs/dotenvy/latest/dotenvy/fn.from_read_iter.html)
- override support via [`dotenv_override`], [`from_filename_override`], [`from_path_override`] and [`from_read_override`]
- improved docs

For a full list of changes, refer to the [changelog](./CHANGELOG.md).
Expand Down
98 changes: 69 additions & 29 deletions dotenv/src/lib.rs
Expand Up @@ -31,8 +31,11 @@ static START: Once = Once::new();
/// # Examples:
///
/// ```no_run
/// let value = dotenvy::var("HOME").unwrap();
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
LeoniePhiline marked this conversation as resolved.
Show resolved Hide resolved
/// let value = dotenvy::var("HOME")?;
/// println!("{}", value); // prints `/home/foo`
/// # Ok(())
/// # }
/// ```
pub fn var<K: AsRef<OsStr>>(key: K) -> Result<String> {
START.call_once(|| {
Expand Down Expand Up @@ -72,10 +75,12 @@ pub fn vars() -> Vars {
/// # Examples
///
/// ```no_run
/// use dirs::home_dir;
/// use std::path::Path;
///
/// let my_path = home_dir().map(|a| a.join("/absolute/path/.env")).unwrap();
/// dotenvy::from_path(my_path.as_path());
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// dotenvy::from_path(Path::new("path/to/.env"))?;
/// # Ok(())
/// # }
LeoniePhiline marked this conversation as resolved.
Show resolved Hide resolved
/// ```
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<()> {
let iter = Iter::new(File::open(path).map_err(Error::Io)?);
Expand All @@ -95,10 +100,12 @@ pub fn from_path<P: AsRef<Path>>(path: P) -> Result<()> {
/// # Examples
///
/// ```no_run
/// use dirs::home_dir;
/// use std::path::Path;
///
/// let my_path = home_dir().map(|a| a.join("/absolute/path/.env")).unwrap();
/// dotenvy::from_path_override(my_path.as_path());
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// dotenvy::from_path_override(Path::new("path/to/.env"))?;
/// # Ok(())
/// # }
/// ```
pub fn from_path_override<P: AsRef<Path>>(path: P) -> Result<()> {
let iter = Iter::new(File::open(path).map_err(Error::Io)?);
Expand All @@ -110,14 +117,15 @@ pub fn from_path_override<P: AsRef<Path>>(path: P) -> Result<()> {
/// # Examples
///
/// ```no_run
/// use dirs::home_dir;
/// use std::path::Path;
///
/// let my_path = home_dir().map(|a| a.join("/absolute/path/.env")).unwrap();
///
/// for item in dotenvy::from_path_iter(my_path.as_path()).unwrap() {
/// let (key, val) = item.unwrap();
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// for item in dotenvy::from_path_iter(Path::new("path/to/.env"))? {
/// let (key, val) = item?;
/// println!("{}={}", key, val);
/// }
/// # Ok(())
/// # }
/// ```
pub fn from_path_iter<P: AsRef<Path>>(path: P) -> Result<Iter<File>> {
Ok(Iter::new(File::open(path).map_err(Error::Io)?))
Expand All @@ -136,13 +144,19 @@ pub fn from_path_iter<P: AsRef<Path>>(path: P) -> Result<Iter<File>> {
///
/// # Examples
/// ```no_run
/// dotenvy::from_filename("custom.env").unwrap();
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// dotenvy::from_filename("custom.env")?;
/// # Ok(())
/// # }
/// ```
///
/// It is also possible to load from a typical *.env* file like so. However, using [`dotenv`] is preferred.
///
/// ```
/// dotenvy::from_filename(".env").unwrap();
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// dotenvy::from_filename(".env")?;
/// # Ok(())
/// # }
/// ```
pub fn from_filename<P: AsRef<Path>>(filename: P) -> Result<PathBuf> {
let (path, iter) = Finder::new().filename(filename.as_ref()).find()?;
Expand All @@ -162,13 +176,19 @@ pub fn from_filename<P: AsRef<Path>>(filename: P) -> Result<PathBuf> {
///
/// # Examples
/// ```no_run
/// dotenvy::from_filename_override("custom.env").unwrap();
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// dotenvy::from_filename_override("custom.env")?;
/// # Ok(())
/// # }
/// ```
///
/// It is also possible to load from a typical *.env* file like so. However, using [`dotenv_override`] is preferred.
///
/// ```
/// dotenvy::from_filename_override(".env").unwrap();
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// dotenvy::from_filename_override(".env")?;
/// # Ok(())
/// # }
/// ```
pub fn from_filename_override<P: AsRef<Path>>(filename: P) -> Result<PathBuf> {
let (path, iter) = Finder::new().filename(filename.as_ref()).find()?;
Expand All @@ -181,10 +201,13 @@ pub fn from_filename_override<P: AsRef<Path>>(filename: P) -> Result<PathBuf> {
/// # Examples
///
/// ```no_run
/// for item in dotenvy::from_filename_iter("custom.env").unwrap() {
/// let (key, val) = item.unwrap();
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// for item in dotenvy::from_filename_iter("custom.env")? {
/// let (key, val) = item?;
/// println!("{}={}", key, val);
/// }
/// # Ok(())
/// # }
/// ```

pub fn from_filename_iter<P: AsRef<Path>>(filename: P) -> Result<Iter<File>> {
Expand Down Expand Up @@ -214,8 +237,11 @@ pub fn from_filename_iter<P: AsRef<Path>>(filename: P) -> Result<Iter<File>> {
/// use std::io::Read;
/// use std::os::unix::net::UnixStream;
///
/// let mut stream = UnixStream::connect("/some/socket").unwrap();
/// dotenvy::from_read(stream).unwrap();
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let mut stream = UnixStream::connect("/some/socket")?;
/// dotenvy::from_read(stream)?;
/// # Ok(())
/// # }
/// ```
pub fn from_read<R: io::Read>(reader: R) -> Result<()> {
let iter = Iter::new(reader);
Expand Down Expand Up @@ -243,8 +269,11 @@ pub fn from_read<R: io::Read>(reader: R) -> Result<()> {
/// use std::io::Read;
/// use std::os::unix::net::UnixStream;
///
/// let mut stream = UnixStream::connect("/some/socket").unwrap();
/// dotenvy::from_read_override(stream).unwrap();
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let mut stream = UnixStream::connect("/some/socket")?;
/// dotenvy::from_read_override(stream)?;
/// # Ok(())
/// # }
/// ```
pub fn from_read_override<R: io::Read>(reader: R) -> Result<()> {
let iter = Iter::new(reader);
Expand All @@ -261,12 +290,15 @@ pub fn from_read_override<R: io::Read>(reader: R) -> Result<()> {
/// use std::io::Read;
/// use std::os::unix::net::UnixStream;
///
/// let mut stream = UnixStream::connect("/some/socket").unwrap();
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let mut stream = UnixStream::connect("/some/socket")?;
///
/// for item in dotenvy::from_read_iter(stream) {
/// let (key, val) = item.unwrap();
/// let (key, val) = item?;
/// println!("{}={}", key, val);
/// }
/// # Ok(())
/// # }
/// ```
pub fn from_read_iter<R: io::Read>(reader: R) -> Iter<R> {
Iter::new(reader)
Expand All @@ -288,7 +320,10 @@ pub fn from_read_iter<R: io::Read>(reader: R) -> Iter<R> {
/// # Examples
///
/// ```
/// dotenvy::dotenv().unwrap();
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// dotenvy::dotenv()?;
/// # Ok(())
/// # }
/// ```
pub fn dotenv() -> Result<PathBuf> {
let (path, iter) = Finder::new().find()?;
Expand All @@ -308,8 +343,10 @@ pub fn dotenv() -> Result<PathBuf> {
///
/// # Examples
/// ```
/// use dotenvy::dotenv_override;
/// dotenv_override().ok();
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// dotenvy::dotenv_override()?;
/// # Ok(())
/// # }
/// ```
pub fn dotenv_override() -> Result<PathBuf> {
let (path, iter) = Finder::new().find()?;
Expand All @@ -322,10 +359,13 @@ pub fn dotenv_override() -> Result<PathBuf> {
/// # Examples
///
/// ```
/// for item in dotenvy::dotenv_iter().unwrap() {
/// let (key, val) = item.unwrap();
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// for item in dotenvy::dotenv_iter()? {
/// let (key, val) = item?;
/// println!("{}={}", key, val);
/// }
/// # Ok(())
/// # }
/// ```
pub fn dotenv_iter() -> Result<iter::Iter<File>> {
let (_, iter) = Finder::new().find()?;
Expand Down