1use std::fmt;
2use std::io::IoSlice;
3use std::pin::Pin;
4use std::task::{Context as TaskContext, Poll};
5use tokio::io::{AsyncRead, AsyncWrite, Error as IoError, ReadBuf, Result as IoResult};
6
7#[macro_export]
8#[doc(hidden)]
9macro_rules! __impl_either {
12 ($macro:ident) => {
13 $macro!(Either, A, B,);
14 $macro!(Either3, A, B, C,);
15 $macro!(Either4, A, B, C, D,);
16 $macro!(Either5, A, B, C, D, E,);
17 $macro!(Either6, A, B, C, D, E, F,);
18 $macro!(Either7, A, B, C, D, E, F, G,);
19 $macro!(Either8, A, B, C, D, E, F, G, H,);
20 $macro!(Either9, A, B, C, D, E, F, G, H, I,);
21 };
22}
23
24#[doc(inline)]
25pub use crate::__impl_either as impl_either;
26
27#[macro_export]
28#[doc(hidden)]
29macro_rules! __define_either {
30 ($id:ident, $($param:ident),+ $(,)?) => {
31 pub enum $id<$($param),+> {
40 $(
41 $param($param),
43 )+
44 }
45
46 impl<$($param),+> Clone for $id<$($param),+>
47 where
48 $($param: Clone),+
49 {
50 fn clone(&self) -> Self {
51 match self {
52 $(
53 $id::$param(s) => $id::$param(s.clone()),
54 )+
55 }
56 }
57 }
58
59 impl<$($param),+> fmt::Debug for $id<$($param),+>
60 where
61 $($param: fmt::Debug),+
62 {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 match self {
65 $(
66 $id::$param(s) => write!(f, "{:?}", s),
67 )+
68 }
69 }
70 }
71
72 impl<$($param),+> fmt::Display for $id<$($param),+>
73 where
74 $($param: fmt::Display),+
75 {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 match self {
78 $(
79 $id::$param(s) => write!(f, "{}", s),
80 )+
81 }
82 }
83 }
84
85
86 impl<$($param),+> $id<$($param),+> {
87 fn as_pin_mut(self: Pin<&mut Self>) -> $id<$(Pin<&mut $param>),+> {
90 unsafe {
96 match self.get_unchecked_mut() {
97 $(
98 Self::$param(inner) => $id::$param(Pin::new_unchecked(inner)),
99 )+
100 }
101 }
102 }
103 }
104
105 impl<$($param),+, Output> std::future::Future for $id<$($param),+>
106 where
107 $($param: Future<Output = Output>),+
108 {
109 type Output = Output;
110
111 fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
112 match self.as_pin_mut() {
113 $(
114 $id::$param(fut) => fut.poll(cx),
115 )+
116 }
117 }
118 }
119 };
120}
121
122#[doc(inline)]
123pub use crate::__define_either as define_either;
124
125impl_either!(define_either);
126
127#[macro_export]
128#[doc(hidden)]
129macro_rules! __impl_iterator_either {
130 ($id:ident, $($param:ident),+ $(,)?) => {
131 impl<$($param),+, Item> Iterator for $id<$($param),+>
132 where
133 $($param: Iterator<Item = Item>),+,
134 {
135 type Item = Item;
136
137 fn next(&mut self) -> Option<Item> {
138 match self {
139 $(
140 $id::$param(iter) => iter.next(),
141 )+
142 }
143 }
144
145 fn size_hint(&self) -> (usize, Option<usize>) {
146 match self {
147 $(
148 $id::$param(iter) => iter.size_hint(),
149 )+
150 }
151 }
152 }
153 };
154}
155
156#[doc(inline)]
157pub use crate::__impl_iterator_either as impl_iterator_either;
158
159impl_either!(impl_iterator_either);
160
161#[macro_export]
162#[doc(hidden)]
163macro_rules! __impl_async_read_write_either {
164 ($id:ident, $($param:ident),+ $(,)?) => {
165 impl<$($param),+> AsyncRead for $id<$($param),+>
166 where
167 $($param: AsyncRead),+,
168 {
169 fn poll_read(
170 self: Pin<&mut Self>,
171 cx: &mut TaskContext<'_>,
172 buf: &mut ReadBuf<'_>,
173 ) -> Poll<IoResult<()>> {
174 match self.as_pin_mut() {
175 $(
176 $id::$param(reader) => reader.poll_read(cx, buf),
177 )+
178 }
179 }
180 }
181
182 impl<$($param),+> AsyncWrite for $id<$($param),+>
183 where
184 $($param: AsyncWrite),+,
185 {
186 fn poll_write(
187 self: Pin<&mut Self>,
188 cx: &mut TaskContext<'_>,
189 buf: &[u8],
190 ) -> Poll<Result<usize, IoError>> {
191 match self.as_pin_mut() {
192 $(
193 $id::$param(writer) => writer.poll_write(cx, buf),
194 )+
195 }
196 }
197
198 fn poll_flush(self: Pin<&mut Self>, cx: &mut TaskContext<'_>) -> Poll<Result<(), IoError>> {
199 match self.as_pin_mut() {
200 $(
201 $id::$param(writer) => writer.poll_flush(cx),
202 )+
203 }
204 }
205
206 fn poll_shutdown(self: Pin<&mut Self>, cx: &mut TaskContext<'_>) -> Poll<Result<(), IoError>> {
207 match self.as_pin_mut() {
208 $(
209 $id::$param(writer) => writer.poll_shutdown(cx),
210 )+
211 }
212 }
213
214 fn poll_write_vectored(
215 self: Pin<&mut Self>,
216 cx: &mut TaskContext<'_>,
217 bufs: &[IoSlice<'_>],
218 ) -> Poll<Result<usize, IoError>> {
219 match self.as_pin_mut() {
220 $(
221 $id::$param(writer) => writer.poll_write_vectored(cx, bufs),
222 )+
223 }
224 }
225
226 fn is_write_vectored(&self) -> bool {
227 match self {
228 $(
229 $id::$param(writer) => writer.is_write_vectored(),
230 )+
231 }
232 }
233 }
234 };
235}
236
237#[doc(inline)]
238pub use crate::__impl_async_read_write_either as impl_async_read_write_either;
239
240impl_either!(impl_async_read_write_either);