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