#![deny(missing_docs)]
pub trait Boolinator: Sized {
fn as_option(self) -> Option<()>;
fn as_some<T>(self, some: T) -> Option<T>;
fn as_some_from<T, F>(self, some: F) -> Option<T>
where F: FnOnce() -> T;
fn and_option<T>(self, opt: Option<T>) -> Option<T>;
fn and_option_from<T, F>(self, opt: F) -> Option<T>
where F: FnOnce() -> Option<T>;
fn as_result<T, E>(self, ok: T, err: E) -> Result<T, E>;
fn as_result_from<T, E, F, G>(self, ok: F, err: G) -> Result<T, E>
where F: FnOnce() -> T, G: FnOnce() -> E;
fn ok_or<E>(self, err: E) -> Result<(), E>;
fn ok_or_else<E, G>(self, err: G) -> Result<(), E>
where G: FnOnce() -> E;
fn expect(self, msg: &str);
}
impl Boolinator for bool {
#[inline]
fn as_option(self) -> Option<()> {
if self { Some(()) } else { None }
}
#[inline]
fn as_some<T>(self, some: T) -> Option<T> {
if self { Some(some) } else { None }
}
#[inline]
fn as_some_from<T, F>(self, some: F) -> Option<T>
where F: FnOnce() -> T {
if self { Some(some()) } else { None }
}
#[inline]
fn and_option<T>(self, opt: Option<T>) -> Option<T> {
if self { opt } else { None }
}
#[inline]
fn and_option_from<T, F>(self, opt: F) -> Option<T>
where F: FnOnce() -> Option<T> {
if self { opt() } else { None }
}
#[inline]
fn as_result<T, E>(self, ok: T, err: E) -> Result<T, E> {
if self { Ok(ok) } else { Err(err) }
}
#[inline]
fn as_result_from<T, E, F, G>(self, ok: F, err: G) -> Result<T, E>
where F: FnOnce() -> T, G: FnOnce() -> E {
if self { Ok(ok()) } else { Err(err()) }
}
#[inline]
fn ok_or<E>(self, err: E) -> Result<(), E> {
if self { Ok(()) } else { Err(err) }
}
#[inline]
fn ok_or_else<E, G>(self, err: G) -> Result<(), E>
where G: FnOnce() -> E {
if self { Ok(()) } else { Err(err()) }
}
#[inline]
fn expect(self, msg: &str) {
if self { () } else { panic!("{}", msg) }
}
}
#[cfg(test)]
mod tests {
use super::Boolinator;
#[test]
fn test_as_option() {
assert_eq!(true.as_option(), Some(()));
assert_eq!(false.as_option(), None);
}
#[test]
fn test_as_some() {
let love = true;
let everybody = love.as_some("body").expect("needs");
assert_eq!(everybody, "body");
assert_eq!((!love).as_some("money can buy"), None);
}
#[test]
fn test_as_some_from() {
let mothers = vec![true, false, false, true, false, true];
assert!(mothers.into_iter()
.map(|e| e.as_some_from(|| Some("em")))
.filter(Option::is_some)
.count() > 0);
}
#[test]
fn test_and_option() {
assert_eq!(true.and_option(Some("fries with that")), Some("fries with that"));
assert_eq!(false.and_option(Some("fries with that")), None);
assert_eq!(true.and_option(None), None::<()>);
assert_eq!(false.and_option(None), None::<()>);
}
#[test]
fn test_and_option_from() {
assert_eq!(true.and_option_from(|| Some("chips too, guv'")), Some("chips too, guv'"));
assert_eq!(false.and_option_from(|| Some("chips too, guv'")), None);
assert_eq!(true.and_option_from(|| None), None::<()>);
assert_eq!(false.and_option_from(|| None), None::<()>);
}
#[test]
fn test_as_result() {
assert_eq!(true.as_result("now; ", ", what?"), Ok("now; "));
assert_eq!(false.as_result("now; ", ", what?"), Err(", what?"));
}
#[test]
fn test_as_result_from() {
assert_eq!(true.as_result_from(|| "four space indent", || "anything else"), Ok("four space indent"));
assert_eq!(false.as_result_from(|| "four space indent", || "anything else"), Err("anything else"));
}
#[test]
fn test_ok_or() {
let mut annie = true;
assert_eq!(annie.ok_or("hit back"), Ok(()));
annie = false;
assert_eq!(annie.ok_or("hit back"), Err("hit back"));
}
#[test]
fn test_ok_or_else() {
let mut annie = true;
assert_eq!(annie.ok_or_else(|| "hit back"), Ok(()));
annie = false;
assert_eq!(annie.ok_or_else(|| "hit back"), Err("hit back"));
}
const DREAMS: &'static str = "love and financial security";
#[test]
fn test_expect() {
true.expect(DREAMS);
}
#[test]
#[should_panic]
fn test_expect_reality() {
false.expect(DREAMS);
}
}