Skip to content
This repository has been archived by the owner on Sep 13, 2023. It is now read-only.

Commit

Permalink
Add trait for ergonomic Options-as-Errors
Browse files Browse the repository at this point in the history
  • Loading branch information
killercup committed Jan 27, 2018
1 parent 1456aef commit 728be3b
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 2 deletions.
57 changes: 57 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use std::fmt::{Debug, Display};
use std::result::Result as StdResult;
use failure::{Error, err_msg};

/// A handy alias for `Result` that carries a generic error type.
pub type Result<T> = StdResult<T, Error>;

/// Treat `Option::None` as Error with context
pub trait NoneErrorContext<T> {
/// Convert Option to Result by annotating what None means
///
/// # Examples
///
/// ```rust
/// # extern crate quicli;
/// # use quicli::prelude::*;
/// # fn main() { assert!(run().is_err()); }
/// # fn run() -> Result<()> {
/// let xs = vec!["lorem", "ipsum"];
/// let x = xs.get(66); // will return None
/// let result = x.none_means("index not found")?;
/// # Ok(()) }
/// ```
fn none_means<E: Display + Debug + Sync + Send + 'static>(self, explanation: E) -> Result<T>;
}

impl<T> NoneErrorContext<T> for Option<T> {
fn none_means<E: Display + Debug + Sync + Send + 'static>(self, explanation: E) -> Result<T> {
match self {
Some(x) => Ok(x),
None => Err(err_msg(explanation)),
}
}
}

#[cfg(test)]
mod tests {
#[test]
fn none_means_error_message() {
use prelude::*;
run().unwrap();

fn run() -> Result<()> {
let xs = vec!["lorem", "ipsum"];
let x = xs.get(66); // will return None

let result = x.none_means("index not found");

assert!(result.is_err());
if let Err(error) = result {
assert_eq!(error.to_string(), "index not found".to_string());
}

Ok(())
}
}
}
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ extern crate env_logger;

pub mod fs;
mod main_macro;
mod errors;

mod reexports {
#[doc(hidden)] pub use serde_derive::*;
Expand All @@ -46,8 +47,7 @@ mod reexports {
pub mod prelude {
pub use reexports::*;

/// A handy alias for `Result` that carries a generic error type.
pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
pub use errors::{Result, NoneErrorContext};

pub use fs::{read_file, write_to_file};

Expand Down

0 comments on commit 728be3b

Please sign in to comment.