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

Commit 728be3b

Browse files
committed
Add trait for ergonomic Options-as-Errors
1 parent 1456aef commit 728be3b

2 files changed

Lines changed: 59 additions & 2 deletions

File tree

src/errors.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use std::fmt::{Debug, Display};
2+
use std::result::Result as StdResult;
3+
use failure::{Error, err_msg};
4+
5+
/// A handy alias for `Result` that carries a generic error type.
6+
pub type Result<T> = StdResult<T, Error>;
7+
8+
/// Treat `Option::None` as Error with context
9+
pub trait NoneErrorContext<T> {
10+
/// Convert Option to Result by annotating what None means
11+
///
12+
/// # Examples
13+
///
14+
/// ```rust
15+
/// # extern crate quicli;
16+
/// # use quicli::prelude::*;
17+
/// # fn main() { assert!(run().is_err()); }
18+
/// # fn run() -> Result<()> {
19+
/// let xs = vec!["lorem", "ipsum"];
20+
/// let x = xs.get(66); // will return None
21+
/// let result = x.none_means("index not found")?;
22+
/// # Ok(()) }
23+
/// ```
24+
fn none_means<E: Display + Debug + Sync + Send + 'static>(self, explanation: E) -> Result<T>;
25+
}
26+
27+
impl<T> NoneErrorContext<T> for Option<T> {
28+
fn none_means<E: Display + Debug + Sync + Send + 'static>(self, explanation: E) -> Result<T> {
29+
match self {
30+
Some(x) => Ok(x),
31+
None => Err(err_msg(explanation)),
32+
}
33+
}
34+
}
35+
36+
#[cfg(test)]
37+
mod tests {
38+
#[test]
39+
fn none_means_error_message() {
40+
use prelude::*;
41+
run().unwrap();
42+
43+
fn run() -> Result<()> {
44+
let xs = vec!["lorem", "ipsum"];
45+
let x = xs.get(66); // will return None
46+
47+
let result = x.none_means("index not found");
48+
49+
assert!(result.is_err());
50+
if let Err(error) = result {
51+
assert_eq!(error.to_string(), "index not found".to_string());
52+
}
53+
54+
Ok(())
55+
}
56+
}
57+
}

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ extern crate env_logger;
2020

2121
pub mod fs;
2222
mod main_macro;
23+
mod errors;
2324

2425
mod reexports {
2526
#[doc(hidden)] pub use serde_derive::*;
@@ -46,8 +47,7 @@ mod reexports {
4647
pub mod prelude {
4748
pub use reexports::*;
4849

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

5252
pub use fs::{read_file, write_to_file};
5353

0 commit comments

Comments
 (0)