1use super::*;
20use ::core::error::Error;
21use ::core::fmt::Display;
22use ::core::ops::{Deref, DerefMut};
23use ::core::pin::Pin;
24use ::core::task::{Context, Poll};
25use ::quither_proc_macros::quither;
26#[cfg(feature = "use_std")]
27use ::std::io::{BufRead, Read, Result as IoResult, Seek, SeekFrom};
28
29#[cfg(feature = "use_std")]
36#[quither]
37impl<L, R> Read for Xither<L, R>
38where
39 L: Read,
40 R: Read,
41{
42 fn read(&mut self, #[allow(unused)] buf: &mut [u8]) -> IoResult<usize> {
43 match self {
44 #[either]
45 Self::Left(l) => l.read(buf),
46 #[either]
47 Self::Right(r) => r.read(buf),
48 #[neither]
49 Self::Neither => Ok(0),
50 #[both]
51 Self::Both(l, r) => {
52 if buf.is_empty() {
53 return Ok(0);
54 }
55 let left_len = l.read(buf)?;
56 if left_len == 0 {
57 r.read(buf)
58 } else {
59 Ok(left_len)
60 }
61 }
62 }
63 }
64}
65
66#[cfg(feature = "use_std")]
73#[quither(!has_both)]
74impl<L, R> BufRead for Xither<L, R>
75where
76 L: BufRead,
77 R: BufRead,
78{
79 fn fill_buf(&mut self) -> IoResult<&[u8]> {
80 match self {
81 #[either]
82 Self::Left(l) => l.fill_buf(),
83 #[either]
84 Self::Right(r) => r.fill_buf(),
85 #[neither]
86 Self::Neither => Ok(&[]),
87 }
88 }
89
90 fn consume(&mut self, #[allow(unused)] amt: usize) {
91 match self {
92 #[either]
93 Self::Left(l) => l.consume(amt),
94 #[either]
95 Self::Right(r) => r.consume(amt),
96 #[neither]
97 Self::Neither => {}
98 }
99 }
100}
101
102#[cfg(feature = "use_std")]
108#[quither(!has_both)]
109impl<L, R> Seek for Xither<L, R>
110where
111 L: Seek,
112 R: Seek,
113{
114 fn seek(&mut self, #[allow(unused)] pos: SeekFrom) -> IoResult<u64> {
115 match self {
116 #[either]
117 Self::Left(l) => l.seek(pos),
118 #[either]
119 Self::Right(r) => r.seek(pos),
120 #[neither]
121 Self::Neither => Ok(0),
122 }
123 }
124}
125
126impl<L, R> Deref for Either<L, R>
131where
132 L: Deref,
133 R: Deref<Target = L::Target>,
134{
135 type Target = L::Target;
136
137 fn deref(&self) -> &Self::Target {
138 match self {
139 Self::Left(l) => l,
140 Self::Right(r) => r,
141 }
142 }
143}
144
145impl<L, R> DerefMut for Either<L, R>
150where
151 L: DerefMut,
152 R: DerefMut<Target = L::Target>,
153{
154 fn deref_mut(&mut self) -> &mut Self::Target {
155 match self {
156 Self::Left(l) => l,
157 Self::Right(r) => r,
158 }
159 }
160}
161
162#[quither]
167impl<L, R> Display for Xither<L, R>
168where
169 L: Display,
170 R: Display,
171{
172 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
173 match self {
174 #[either]
175 Self::Left(l) => write!(f, "Left({})", l),
176 #[either]
177 Self::Right(r) => write!(f, "Right({})", r),
178 #[neither]
179 Self::Neither => write!(f, "Neither"),
180 #[both]
181 Self::Both(l, r) => write!(f, "Both({}, {})", l, r),
182 }
183 }
184}
185
186impl<L, R> Error for Either<L, R>
191where
192 L: Error,
193 R: Error,
194{
195 fn source(&self) -> Option<&(dyn Error + 'static)> {
196 match self {
197 Self::Left(l) => l.source(),
198 Self::Right(r) => r.source(),
199 }
200 }
201
202 #[allow(deprecated)]
203 fn description(&self) -> &str {
204 match self {
205 Self::Left(l) => l.description(),
206 Self::Right(r) => r.description(),
207 }
208 }
209
210 #[allow(deprecated)]
211 fn cause(&self) -> Option<&dyn Error> {
212 match self {
213 Self::Left(l) => l.cause(),
214 Self::Right(r) => r.cause(),
215 }
216 }
217
218 }
220
221#[quither(!has_neither && !has_both)]
227impl<L, R, T> Extend<T> for Xither<L, R>
228where
229 L: Extend<T>,
230 R: Extend<T>,
231{
232 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
233 match self {
234 #[either]
235 Self::Left(l) => l.extend(iter),
236 #[either]
237 Self::Right(r) => r.extend(iter),
238 }
239 }
240}
241
242#[quither(!has_neither && has_both)]
247impl<L, R, T> Extend<T> for Xither<L, R>
248where
249 L: Extend<T>,
250 R: Extend<T>,
251 T: Clone,
252{
253 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
254 match self {
255 #[either]
256 Self::Left(l) => l.extend(iter),
257 #[either]
258 Self::Right(r) => r.extend(iter),
259 #[both]
260 Self::Both(l, r) => {
261 let tuple_iter = iter.into_iter().map(|t| (t.clone(), t));
262
263 struct Wrap<U>(U);
265 impl<U, V> Extend<V> for Wrap<&mut U>
266 where
267 U: Extend<V>,
268 {
269 fn extend<I: IntoIterator<Item = V>>(&mut self, iter: I) {
270 self.0.extend(iter);
271 }
272 }
273 (Wrap(l), Wrap(r)).extend(tuple_iter);
274 }
275 }
276 }
277}
278
279impl<L, R> Future for Either<L, R>
284where
285 L: Future,
286 R: Future<Output = L::Output>,
287{
288 type Output = L::Output;
289 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
290 match self.as_pin_mut() {
291 Either::Left(l) => l.poll(ctx),
292 Either::Right(r) => r.poll(ctx),
293 }
294 }
295}
296
297#[quither]
298impl<L, R, OL, OR> PartialEq<Xither<OL, OR>> for Xither<L, R>
299where
300 L: PartialEq<OL>,
301 R: PartialEq<OR>,
302{
303 fn eq(&self, other: &Xither<OL, OR>) -> bool {
304 match (self, other) {
305 #[either]
306 (Self::Left(l), Xither::Left(ol)) => l == ol,
307 #[either]
308 (Self::Right(r), Xither::Right(or)) => r == or,
309 #[neither]
310 (Self::Neither, Xither::Neither) => true,
311 #[both]
312 (Self::Both(l, r), Xither::Both(ol, or)) => l == ol && r == or,
313 #[allow(unreachable_patterns)]
314 _ => false,
315 }
316 }
317}
318
319#[quither]
320impl<L, R, OL, OR> PartialOrd<Xither<OL, OR>> for Xither<L, R>
321where
322 L: PartialOrd<OL>,
323 R: PartialOrd<OR>,
324{
325 fn partial_cmp(&self, other: &Xither<OL, OR>) -> Option<std::cmp::Ordering> {
326 match (self, other) {
327 #[either]
328 (Self::Left(l), Xither::Left(ol)) => l.partial_cmp(ol),
329 #[either]
330 (Self::Right(r), Xither::Right(or)) => r.partial_cmp(or),
331 #[neither]
332 (Self::Neither, Xither::Neither) => Some(std::cmp::Ordering::Equal),
333 #[both]
334 (Self::Both(l, r), Xither::Both(ol, or)) => l
335 .partial_cmp(ol)
336 .and_then(|o| r.partial_cmp(or).map(|o2| o.cmp(&o2))),
337 #[neither]
339 #[allow(unreachable_patterns)]
340 (Self::Neither, _) => Some(std::cmp::Ordering::Less),
341 #[neither]
342 #[allow(unreachable_patterns)]
343 (_, Xither::Neither) => Some(std::cmp::Ordering::Greater),
344 #[either]
345 #[allow(unreachable_patterns)]
346 (Self::Left(_), _) => Some(std::cmp::Ordering::Less),
347 #[either]
348 #[allow(unreachable_patterns)]
349 (_, Xither::Left(_)) => Some(std::cmp::Ordering::Greater),
350 #[either]
351 #[allow(unreachable_patterns)]
352 (Self::Right(_), _) => Some(std::cmp::Ordering::Less),
353 #[either]
354 #[allow(unreachable_patterns)]
355 (_, Xither::Right(_)) => Some(std::cmp::Ordering::Greater),
356 }
357 }
358}