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());
    }
}