1use std::task::Poll;
2
3pub trait Try {
5 type Ok;
7 type Error;
9
10 fn into_result(self) -> Result<Self::Ok, Self::Error>;
15
16 fn from_error(v: Self::Error) -> Self;
19
20 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
40pub 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#[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}