use std::fmt::Debug;
pub trait ResultExt<T, E>
where
E: Debug,
{
fn todo(self) -> T;
fn assured(self, reason: &str) -> T;
fn verified(self, reason: &str) -> T;
}
impl<T, E> ResultExt<T, E> for Result<T, E>
where
E: Debug,
{
#[inline]
#[track_caller]
#[cfg(not(all(feature = "disallow-todo-on-release", not(debug_assertions))))]
fn todo(self) -> T {
self.expect("not yet implemented")
}
#[inline]
#[track_caller]
fn assured(self, reason: &str) -> T {
if let Ok(ok) = self {
ok
} else {
panic!(
"the success was expected to be assured, but the error was returned: {}",
reason
);
}
}
#[inline]
#[track_caller]
fn verified(self, reason: &str) -> T {
if let Ok(ok) = self {
ok
} else {
panic!("the success was expected to be verified in the code earlier, but the error was returned: {}", reason);
}
}
}
pub trait OptionExt<T> {
fn todo(self) -> T;
fn assured(self, reason: &str) -> T;
fn verified(self, reason: &str) -> T;
}
impl<T> OptionExt<T> for Option<T> {
#[cfg(not(all(feature = "disallow-todo-on-release", not(debug_assertions))))]
#[track_caller]
fn todo(self) -> T {
self.expect("not yet implemented")
}
#[inline]
#[track_caller]
fn assured(self, reason: &str) -> T {
if let Some(some) = self {
some
} else {
panic!("the value was assured to exist but was None: {}", reason);
}
}
#[inline]
#[track_caller]
fn verified(self, reason: &str) -> T {
if let Some(some) = self {
some
} else {
panic!(
"it was verified that value presents but None was returned: {}",
reason
);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic]
fn test_result_todo() {
u16::try_from(i32::MAX).todo();
}
#[test]
#[should_panic]
fn test_result_assured() {
u16::try_from(i32::MAX).assured("always ok on linux");
}
#[test]
#[should_panic]
fn test_result_verified() {
u16::try_from(i32::MAX).verified("boundaries already checked");
}
#[test]
#[should_panic]
fn test_option_todo() {
"hello".strip_prefix("a").todo();
}
#[test]
#[should_panic]
fn test_option_assured() {
"hello"
.strip_prefix("a")
.assured("string always starts with a");
}
#[test]
#[should_panic]
fn test_option_verified() {
"hello"
.strip_prefix("a")
.verified("string prefix was already checked");
}
}