vec_utils/
try.rs

1use std::task::Poll;
2
3/// A stable version of [`core::ops::Try`].
4pub trait Try {
5    /// The type of this value when viewed as successful.
6    type Ok;
7    /// The type of this value when viewed as failed.
8    type Error;
9
10    /// A return of `Ok(t)` means that the
11    /// execution should continue normally, and the result of `?` is the
12    /// value `t`. A return of `Err(e)` means that execution should branch
13    /// to the innermost enclosing `catch`, or return from the function.
14    fn into_result(self) -> Result<Self::Ok, Self::Error>;
15
16    /// Wrap an error value to construct the composite result. For example,
17    /// `Result::Err(x)` and `Result::from_error(x)` are equivalent.
18    fn from_error(v: Self::Error) -> Self;
19
20    /// Wrap an OK value to construct the composite result. For example,
21    /// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent.
22    fn from_ok(v: Self::Ok) -> Self;
23}
24
25impl<T, E> Try for Result<T, E> {
26    type Ok = T;
27    type Error = E;
28
29    fn into_result(self) -> Result<<Self as Try>::Ok, <Self as Try>::Error> {
30        self
31    }
32    fn from_error(v: <Self as Try>::Error) -> Self {
33        Err(v)
34    }
35    fn from_ok(v: <Self as Try>::Ok) -> Self {
36        Ok(v)
37    }
38}
39
40/// The error type that results from applying the try operator (`?`) to a `None` value.
41pub struct NoneError;
42
43impl<T> Try for Option<T> {
44    type Ok = T;
45    type Error = NoneError;
46
47    fn into_result(self) -> Result<<Self as Try>::Ok, <Self as Try>::Error> {
48        self.ok_or(NoneError)
49    }
50    fn from_error(_v: <Self as Try>::Error) -> Self {
51        None
52    }
53    fn from_ok(v: <Self as Try>::Ok) -> Self {
54        Some(v)
55    }
56}
57
58impl<T, E> Try for Poll<Option<Result<T, E>>> {
59    type Ok = Poll<Option<T>>;
60    type Error = E;
61
62    fn into_result(self) -> Result<<Self as Try>::Ok, <Self as Try>::Error> {
63        match self {
64            Poll::Ready(Some(Ok(x))) => Ok(Poll::Ready(Some(x))),
65            Poll::Ready(Some(Err(e))) => Err(e),
66            Poll::Ready(None) => Ok(Poll::Ready(None)),
67            Poll::Pending => Ok(Poll::Pending),
68        }
69    }
70
71    fn from_error(v: <Self as Try>::Error) -> Self {
72        Poll::Ready(Some(Err(v)))
73    }
74
75    fn from_ok(v: <Self as Try>::Ok) -> Self {
76        v.map(|x| x.map(Ok))
77    }
78}
79
80impl<T, E> Try for Poll<Result<T, E>> {
81    type Ok = Poll<T>;
82    type Error = E;
83
84    #[inline]
85    fn into_result(self) -> Result<Self::Ok, Self::Error> {
86        match self {
87            Poll::Ready(Ok(x)) => Ok(Poll::Ready(x)),
88            Poll::Ready(Err(e)) => Err(e),
89            Poll::Pending => Ok(Poll::Pending),
90        }
91    }
92
93    #[inline]
94    fn from_error(e: Self::Error) -> Self {
95        Poll::Ready(Err(e))
96    }
97
98    #[inline]
99    fn from_ok(x: Self::Ok) -> Self {
100        x.map(Ok)
101    }
102}
103
104/// Unwraps a result or propagates its error.
105#[macro_export]
106macro_rules! r#try {
107    ($expr:expr) => {
108        match $crate::Try::into_result($expr) {
109            Ok(val) => val,
110            Err(err) => return $crate::Try::from_error(::core::convert::From::from(err)),
111        }
112    };
113    ($expr:expr,) => {
114        $crate::r#try!($expr)
115    };
116}