1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
use core::convert::Infallible;
pub(crate) trait IsInfallible {}
impl IsInfallible for Infallible {}
/// This extension trait adds [InfallibleResultExt::infallible_unwrap] to [Result] types
/// that use [core::convert::Infallible] as error type.
pub trait InfallibleResultExt<T> {
/// This function does the same as [Result::unwrap], but it only exists on types where the error type
/// of the [Result] is [core::convert::Infallible]. This way, we can guarantee that this function
/// will always be a no-op and will never panic. This is great for when your code style says that
/// [Result::unwrap] is a code smell because it could cause runtime panics, but you need a safe
/// alternative for it for when you know it can't fail.
fn infallible_unwrap(self) -> T;
}
impl<T, E> InfallibleResultExt<T> for Result<T, E>
where
E: IsInfallible,
{
fn infallible_unwrap(self) -> T {
match self {
Ok(value) => value,
Err(_) => unreachable!(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn infallible_unwrap() {
let value: Result<u32, Infallible> = Ok(2);
assert_eq!(2, value.infallible_unwrap());
}
struct AlternativeInfallible {}
impl IsInfallible for AlternativeInfallible {}
#[test]
fn alternative_infallible_unwrap() {
let value: Result<u32, AlternativeInfallible> = Ok(2);
assert_eq!(2, value.infallible_unwrap());
}
}