Skip to main content

either_or_both/either/
traits.rs

1//! The traits implemented for `Either`
2
3use core::cmp::Ordering;
4use core::fmt::{self, Display};
5use core::future::Future;
6use core::ops::{Deref, DerefMut};
7use core::pin::Pin;
8#[cfg(feature = "std")]
9use std::error::Error;
10#[cfg(feature = "std")]
11use std::io::{BufRead, Read, Seek};
12
13use crate::iter_either::{IntoIterEither, IterEither, IterMutEither};
14use crate::Either;
15
16impl<L, R, T> AsMut<T> for Either<L, R>
17where
18    T: ?Sized,
19    L: AsMut<T>,
20    R: AsMut<T>,
21{
22    #[inline]
23    fn as_mut(&mut self) -> &mut T {
24        each!(self, .as_mut())
25    }
26}
27
28impl<L, R, T> AsRef<T> for Either<L, R>
29where
30    T: ?Sized,
31    L: AsRef<T>,
32    R: AsRef<T>,
33{
34    #[inline]
35    fn as_ref(&self) -> &T {
36        each!(self, .as_ref())
37    }
38}
39
40#[cfg(feature = "std")]
41impl<L, R> BufRead for Either<L, R>
42where
43    L: BufRead,
44    R: BufRead,
45{
46    fn fill_buf(&mut self) -> std::io::Result<&[u8]> {
47        each!(self, .fill_buf())
48    }
49
50    fn consume(&mut self, amount: usize) {
51        each!(self, .consume(amount));
52    }
53}
54
55impl<L, R> Deref for Either<L, R>
56where
57    L: Deref<Target = R::Target>,
58    R: Deref,
59{
60    type Target = R::Target;
61
62    #[inline]
63    fn deref(&self) -> &Self::Target {
64        each!(self)
65    }
66}
67
68impl<L, R> DerefMut for Either<L, R>
69where
70    L: DerefMut<Target = R::Target>,
71    R: DerefMut,
72{
73    #[inline]
74    fn deref_mut(&mut self) -> &mut Self::Target {
75        each!(self)
76    }
77}
78
79impl<L, R> Display for Either<L, R>
80where
81    L: Display,
82    R: Display,
83{
84    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85        each!(self, .fmt(f))
86    }
87}
88
89#[cfg(feature = "std")]
90impl<L, R> Error for Either<L, R>
91where
92    L: Error,
93    R: Error,
94{
95    fn source(&self) -> Option<&(dyn Error + 'static)> {
96        each!(self, .source())
97    }
98}
99
100impl<A, T> Extend<A> for Either<T>
101where
102    T: Extend<A>,
103{
104    fn extend<I>(&mut self, iter: I)
105    where
106        I: IntoIterator<Item = A>,
107    {
108        each!(self, .extend(iter));
109    }
110}
111
112impl<'a, L, R> From<&'a Either<L, R>> for Either<&'a L, &'a R> {
113    #[inline]
114    fn from(value: &'a Either<L, R>) -> Self {
115        value.as_ref()
116    }
117}
118
119impl<'a, L, R> From<&'a mut Either<L, R>> for Either<&'a mut L, &'a mut R> {
120    #[inline]
121    fn from(value: &'a mut Either<L, R>) -> Self {
122        value.as_mut()
123    }
124}
125
126impl<L, R> From<Result<R, L>> for Either<L, R> {
127    #[inline]
128    fn from(value: Result<R, L>) -> Self {
129        match value {
130            Ok(ok) => Self::Right(ok),
131            Err(err) => Self::Left(err),
132        }
133    }
134}
135
136impl<L, R> Future for Either<L, R>
137where
138    L: Future<Output = R::Output>,
139    R: Future,
140{
141    type Output = R::Output;
142
143    fn poll(
144        self: Pin<&mut Self>,
145        cx: &mut core::task::Context<'_>,
146    ) -> core::task::Poll<Self::Output> {
147        match self.as_pin_mut() {
148            Either::Left(left) => left.poll(cx),
149            Either::Right(right) => right.poll(cx),
150        }
151    }
152}
153
154impl<T> IntoIterator for Either<T> {
155    type Item = T;
156    type IntoIter = IntoIterEither<T>;
157
158    fn into_iter(self) -> Self::IntoIter {
159        IntoIterEither::new(self)
160    }
161}
162
163impl<'a, T> IntoIterator for &'a Either<T> {
164    type Item = &'a T;
165    type IntoIter = IterEither<'a, T>;
166
167    fn into_iter(self) -> Self::IntoIter {
168        IterEither::new(self)
169    }
170}
171
172impl<'a, T> IntoIterator for &'a mut Either<T> {
173    type Item = &'a mut T;
174    type IntoIter = IterMutEither<'a, T>;
175
176    fn into_iter(self) -> Self::IntoIter {
177        IterMutEither::new(self)
178    }
179}
180
181impl<L, R> Ord for Either<L, R>
182where
183    L: Ord,
184    R: Ord,
185{
186    /// Compares two [`Either`] values using the ordering `Left < Right`.
187    ///
188    /// When both values are the same variant, their inner values are compared directly.
189    ///
190    /// # Examples
191    ///
192    /// ```
193    /// use either_or_both::Either;
194    ///
195    /// // Left is less than Right
196    /// assert!(Either::<u8, u8>::Left(5) < Either::Right(1));
197    ///
198    /// // Same variants compare inner values
199    /// assert!(Either::<u8, u8>::Left(1) < Either::Left(2));
200    /// assert!(Either::<u8, u8>::Right(1) < Either::Right(2));
201    /// ```
202    fn cmp(&self, other: &Self) -> Ordering {
203        match (self, other) {
204            (Self::Left(a), Self::Left(b)) => a.cmp(b),
205            (Self::Left(_), Self::Right(_)) => Ordering::Less,
206            (Self::Right(a), Self::Right(b)) => a.cmp(b),
207            (Self::Right(_), Self::Left(_)) => Ordering::Greater,
208        }
209    }
210}
211
212impl<L, R> PartialOrd for Either<L, R>
213where
214    L: Ord,
215    R: Ord,
216{
217    /// Compares two [`Either`] values using the same ordering as [`Ord::cmp`].
218    ///
219    /// [`Either`] always has a total ordering, so this always returns `Some`.
220    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
221        Some(self.cmp(other))
222    }
223}
224
225#[cfg(feature = "std")]
226impl<L, R> Read for Either<L, R>
227where
228    L: Read,
229    R: Read,
230{
231    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
232        each!(self, .read(buf))
233    }
234}
235
236#[cfg(feature = "std")]
237impl<L, R> Seek for Either<L, R>
238where
239    L: Seek,
240    R: Seek,
241{
242    fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
243        each!(self, .seek(pos))
244    }
245}
246
247impl<L, R> fmt::Write for Either<L, R>
248where
249    L: fmt::Write,
250    R: fmt::Write,
251{
252    fn write_str(&mut self, s: &str) -> fmt::Result {
253        each!(self, .write_str(s))
254    }
255}
256
257#[cfg(feature = "std")]
258impl<L, R> std::io::Write for Either<L, R>
259where
260    L: std::io::Write,
261    R: std::io::Write,
262{
263    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
264        each!(self, .write(buf))
265    }
266
267    fn flush(&mut self) -> std::io::Result<()> {
268        each!(self, .flush())
269    }
270}