1#[cfg(not(feature = "nightly"))]
7pub use stable::{FromResidual, Try};
8#[cfg(feature = "nightly")]
9pub use std::ops::{FromResidual, Try};
10
11mod stable {
12 use std::{convert, ops::ControlFlow, task::Poll};
13
14 pub trait Try: FromResidual {
15 type Output;
16 type Residual;
17
18 fn from_output(output: Self::Output) -> Self;
19 fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
20 }
21
22 pub trait FromResidual<R = <Self as Try>::Residual> {
23 fn from_residual(residual: R) -> Self;
24 }
25
26 impl<B, C> Try for ControlFlow<B, C> {
27 type Output = C;
28 type Residual = ControlFlow<B, convert::Infallible>;
29
30 #[inline]
31 fn from_output(output: Self::Output) -> Self {
32 ControlFlow::Continue(output)
33 }
34
35 #[inline]
36 fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
37 match self {
38 ControlFlow::Continue(c) => ControlFlow::Continue(c),
39 ControlFlow::Break(b) => ControlFlow::Break(ControlFlow::Break(b)),
40 }
41 }
42 }
43
44 impl<B, C> FromResidual for ControlFlow<B, C> {
45 #[inline]
46 fn from_residual(residual: ControlFlow<B, convert::Infallible>) -> Self {
47 match residual {
48 ControlFlow::Break(b) => ControlFlow::Break(b),
49 _ => unreachable!(),
50 }
51 }
52 }
53
54 impl<T> Try for Option<T> {
55 type Output = T;
56 type Residual = Option<convert::Infallible>;
57
58 #[inline]
59 fn from_output(output: Self::Output) -> Self {
60 Some(output)
61 }
62
63 #[inline]
64 fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
65 match self {
66 Some(v) => ControlFlow::Continue(v),
67 None => ControlFlow::Break(None),
68 }
69 }
70 }
71
72 impl<T> FromResidual for Option<T> {
73 #[inline]
74 fn from_residual(residual: Option<convert::Infallible>) -> Self {
75 match residual {
76 None => None,
77 _ => unreachable!(),
78 }
79 }
80 }
81
82 impl<T, E> Try for Result<T, E> {
83 type Output = T;
84 type Residual = Result<convert::Infallible, E>;
85
86 #[inline]
87 fn from_output(output: Self::Output) -> Self {
88 Ok(output)
89 }
90
91 #[inline]
92 fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
93 match self {
94 Ok(v) => ControlFlow::Continue(v),
95 Err(e) => ControlFlow::Break(Err(e)),
96 }
97 }
98 }
99
100 impl<T, E, F: From<E>> FromResidual<Result<convert::Infallible, E>> for Result<T, F> {
101 #[inline]
102 fn from_residual(residual: Result<convert::Infallible, E>) -> Self {
103 match residual {
104 Err(e) => Err(From::from(e)),
105 _ => unreachable!(),
106 }
107 }
108 }
109
110 impl<T, E> Try for Poll<Option<Result<T, E>>> {
111 type Output = Poll<Option<T>>;
112 type Residual = Result<convert::Infallible, E>;
113
114 #[inline]
115 fn from_output(c: Self::Output) -> Self {
116 c.map(|x| x.map(Ok))
117 }
118
119 #[inline]
120 fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
121 match self {
122 Poll::Ready(Some(Ok(x))) => ControlFlow::Continue(Poll::Ready(Some(x))),
123 Poll::Ready(Some(Err(e))) => ControlFlow::Break(Err(e)),
124 Poll::Ready(None) => ControlFlow::Continue(Poll::Ready(None)),
125 Poll::Pending => ControlFlow::Continue(Poll::Pending),
126 }
127 }
128 }
129
130 impl<T, E, F: From<E>> FromResidual<Result<convert::Infallible, E>> for Poll<Option<Result<T, F>>> {
131 #[inline]
132 fn from_residual(x: Result<convert::Infallible, E>) -> Self {
133 match x {
134 Err(e) => Poll::Ready(Some(Err(From::from(e)))),
135 _ => unreachable!(),
136 }
137 }
138 }
139
140 impl<T, E> Try for Poll<Result<T, E>> {
141 type Output = Poll<T>;
142 type Residual = Result<convert::Infallible, E>;
143
144 #[inline]
145 fn from_output(c: Self::Output) -> Self {
146 c.map(Ok)
147 }
148
149 #[inline]
150 fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
151 match self {
152 Poll::Ready(Ok(x)) => ControlFlow::Continue(Poll::Ready(x)),
153 Poll::Ready(Err(e)) => ControlFlow::Break(Err(e)),
154 Poll::Pending => ControlFlow::Continue(Poll::Pending),
155 }
156 }
157 }
158
159 impl<T, E, F: From<E>> FromResidual<Result<convert::Infallible, E>> for Poll<Result<T, F>> {
160 #[inline]
161 fn from_residual(x: Result<convert::Infallible, E>) -> Self {
162 match x {
163 Err(e) => Poll::Ready(Err(From::from(e))),
164 _ => unreachable!(),
165 }
166 }
167 }
168}