either/
lib.rs

1//! The enum [**Either**](enum.Either.html).
2//!
3//! Crate features:
4//!
5//! * `"use_std"`
6//! Enabled by default. Disable to make the library `#![no_std]`.
7//!
8
9#![doc(html_root_url = "https://docs.rs/either/1/")]
10#![cfg_attr(all(not(test), not(feature = "use_std")), no_std)]
11#[cfg(all(not(test), not(feature = "use_std")))]
12extern crate core as std;
13
14use std::fmt;
15use std::convert::{AsRef, AsMut};
16use std::ops::Deref;
17use std::ops::DerefMut;
18#[cfg(any(test, feature = "use_std"))]
19use std::io::{self, Write, Read, BufRead};
20#[cfg(any(test, feature = "use_std"))]
21use std::error::Error;
22
23pub use Either::{Left, Right};
24
25/// `Either` represents an alternative holding one value out of
26/// either of the two possible values.
27///
28/// `Either` is a general purpose sum type of two parts. For representing
29/// success or error, use the regular `Result<T, E>` instead.
30#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
31pub enum Either<L, R> {
32    /// A value of type `L`.
33    Left(L),
34    /// A value of type `R`.
35    Right(R),
36}
37
38macro_rules! either {
39    ($value:expr, $pattern:pat => $result:expr) => (
40        match $value {
41            Either::Left($pattern) => $result,
42            Either::Right($pattern) => $result,
43        }
44    )
45}
46
47/// Macro for unwrapping the left side of an `Either`, which fails early
48/// with the opposite side. Can only be used in functions that return
49/// `Either` because of the early return of `Right` that it provides.
50///
51/// See also `try_right!` for its dual, which applies the same just to the
52/// right side.
53///
54/// # Example
55///
56/// ```
57/// #[macro_use] extern crate either;
58/// use either::{Either, Left, Right};
59///
60/// fn twice(wrapper: Either<u32, &str>) -> Either<u32, &str> {
61///     let value = try_left!(wrapper);
62///     Left(value * 2)
63/// }
64///
65/// fn main() {
66///     assert_eq!(twice(Left(2)), Left(4));
67///     assert_eq!(twice(Right("ups")), Right("ups"));
68/// }
69/// ```
70#[macro_export]
71macro_rules! try_left {
72    ($expr:expr) => (
73        match $expr {
74            $crate::Left(val) => val,
75            $crate::Right(err) => return $crate::Right(::std::convert::From::from(err))
76        }
77    )
78}
79
80/// Dual to `try_left!`, see its documentation for more information.
81#[macro_export]
82macro_rules! try_right {
83    ($expr:expr) => (
84        match $expr {
85            $crate::Left(err) => return $crate::Left(::std::convert::From::from(err)),
86            $crate::Right(val) => val
87        }
88    )
89}
90
91impl<L, R> Either<L, R> {
92    /// Return true if the value is the `Left` variant.
93    ///
94    /// ```
95    /// use either::*;
96    ///
97    /// let values = [Left(1), Right("the right value")];
98    /// assert_eq!(values[0].is_left(), true);
99    /// assert_eq!(values[1].is_left(), false);
100    /// ```
101    pub fn is_left(&self) -> bool {
102        match *self {
103            Left(_) => true,
104            Right(_) => false,
105        }
106    }
107
108    /// Return true if the value is the `Right` variant.
109    ///
110    /// ```
111    /// use either::*;
112    ///
113    /// let values = [Left(1), Right("the right value")];
114    /// assert_eq!(values[0].is_right(), false);
115    /// assert_eq!(values[1].is_right(), true);
116    /// ```
117    pub fn is_right(&self) -> bool {
118        !self.is_left()
119    }
120
121    /// Convert the left side of `Either<L, R>` to an `Option<L>`.
122    ///
123    /// ```
124    /// use either::*;
125    ///
126    /// let left: Either<_, ()> = Left("some value");
127    /// assert_eq!(left.left(),  Some("some value"));
128    ///
129    /// let right: Either<(), _> = Right(321);
130    /// assert_eq!(right.left(), None);
131    /// ```
132    pub fn left(self) -> Option<L> {
133        match self {
134            Left(l) => Some(l),
135            Right(_) => None,
136        }
137    }
138
139    /// Convert the right side of `Either<L, R>` to an `Option<R>`.
140    ///
141    /// ```
142    /// use either::*;
143    ///
144    /// let left: Either<_, ()> = Left("some value");
145    /// assert_eq!(left.right(),  None);
146    ///
147    /// let right: Either<(), _> = Right(321);
148    /// assert_eq!(right.right(), Some(321));
149    /// ```
150    pub fn right(self) -> Option<R> {
151        match self {
152            Left(_) => None,
153            Right(r) => Some(r),
154        }
155    }
156
157    /// Convert `&Either<L, R>` to `Either<&L, &R>`.
158    ///
159    /// ```
160    /// use either::*;
161    ///
162    /// let left: Either<_, ()> = Left("some value");
163    /// assert_eq!(left.as_ref(), Left(&"some value"));
164    ///
165    /// let right: Either<(), _> = Right("some value");
166    /// assert_eq!(right.as_ref(), Right(&"some value"));
167    /// ```
168    pub fn as_ref(&self) -> Either<&L, &R> {
169        match *self {
170            Left(ref inner) => Left(inner),
171            Right(ref inner) => Right(inner),
172        }
173    }
174
175    /// Convert `&mut Either<L, R>` to `Either<&mut L, &mut R>`.
176    ///
177    /// ```
178    /// use either::*;
179    ///
180    /// fn mutate_left(value: &mut Either<u32, u32>) {
181    ///     if let Some(l) = value.as_mut().left() {
182    ///         *l = 999;
183    ///     }
184    /// }
185    ///
186    /// let mut left = Left(123);
187    /// let mut right = Right(123);
188    /// mutate_left(&mut left);
189    /// mutate_left(&mut right);
190    /// assert_eq!(left, Left(999));
191    /// assert_eq!(right, Right(123));
192    /// ```
193    pub fn as_mut(&mut self) -> Either<&mut L, &mut R> {
194        match *self {
195            Left(ref mut inner) => Left(inner),
196            Right(ref mut inner) => Right(inner),
197        }
198    }
199
200    /// Convert `Either<L, R>` to `Either<R, L>`.
201    ///
202    /// ```
203    /// use either::*;
204    ///
205    /// let left: Either<_, ()> = Left(123);
206    /// assert_eq!(left.flip(), Right(123));
207    ///
208    /// let right: Either<(), _> = Right("some value");
209    /// assert_eq!(right.flip(), Left("some value"));
210    /// ```
211    pub fn flip(self) -> Either<R, L> {
212        match self {
213            Left(l) => Right(l),
214            Right(r) => Left(r),
215        }
216    }
217
218    /// Apply the function `f` on the value in the `Left` variant if it is present.
219    ///
220    /// ```
221    /// use either::*;
222    ///
223    /// let left: Either<_, u32> = Left(123);
224    /// assert_eq!(left.map_left(|x| x * 2), Left(246));
225    ///
226    /// let right: Either<u32, _> = Right(123);
227    /// assert_eq!(right.map_left(|x| x * 2), Right(123));
228    /// ```
229    pub fn map_left<F, M>(self, f: F) -> Either<M, R>
230        where F: FnOnce(L) -> M
231    {
232        match self {
233            Left(l) => Left(f(l)),
234            Right(r) => Right(r),
235        }
236    }
237
238    /// Apply the function `f` on the value in the `Right` variant if it is present.
239    ///
240    /// ```
241    /// use either::*;
242    ///
243    /// let left: Either<_, u32> = Left(123);
244    /// assert_eq!(left.map_right(|x| x * 2), Left(123));
245    ///
246    /// let right: Either<u32, _> = Right(123);
247    /// assert_eq!(right.map_right(|x| x * 2), Right(246));
248    /// ```
249    pub fn map_right<F, S>(self, f: F) -> Either<L, S>
250        where F: FnOnce(R) -> S
251    {
252        match self {
253            Left(l) => Left(l),
254            Right(r) => Right(f(r)),
255        }
256    }
257
258    /// Apply one of two functions depending on contents, unifying their result. If the value is
259    /// `Left(L)` then the first function `f` is applied; if it is `Right(R)` then the second
260    /// function `g` is applied.
261    ///
262    /// ```
263    /// use either::*;
264    ///
265    /// fn square(n: u32) -> i32 { (n * n) as i32 }
266    /// fn negate(n: i32) -> i32 { -n }
267    ///
268    /// let left: Either<u32, i32> = Left(4);
269    /// assert_eq!(left.either(square, negate), 16);
270    ///
271    /// let right: Either<u32, i32> = Right(-4);
272    /// assert_eq!(right.either(square, negate), 4);
273    /// ```
274    pub fn either<F, G, T>(self, f: F, g: G) -> T
275      where F: FnOnce(L) -> T,
276            G: FnOnce(R) -> T
277    {
278        match self {
279            Left(l) => f(l),
280            Right(r) => g(r),
281        }
282    }
283}
284
285/// Convert from `Result` to `Either` with `Ok => Right` and `Err => Left`.
286impl<L, R> From<Result<R, L>> for Either<L, R> {
287    fn from(r: Result<R, L>) -> Self {
288        match r {
289            Err(e) => Left(e),
290            Ok(o) => Right(o),
291        }
292    }
293}
294
295/// Convert from `Either` to `Result` with `Right => Ok` and `Left => Err`.
296impl<L, R> Into<Result<R, L>> for Either<L, R> {
297    fn into(self) -> Result<R, L> {
298        match self {
299            Left(l) => Err(l),
300            Right(r) => Ok(r),
301        }
302    }
303}
304
305/// `Either<L, R>` is an iterator if both `L` and `R` are iterators.
306impl<L, R> Iterator for Either<L, R>
307    where L: Iterator, R: Iterator<Item=L::Item>
308{
309    type Item = L::Item;
310
311    fn next(&mut self) -> Option<L::Item> {
312        either!(*self, ref mut inner => inner.next())
313    }
314
315    fn size_hint(&self) -> (usize, Option<usize>) {
316        either!(*self, ref inner => inner.size_hint())
317    }
318}
319
320impl<L, R> DoubleEndedIterator for Either<L, R>
321    where L: DoubleEndedIterator, R: DoubleEndedIterator<Item=L::Item>
322{
323    fn next_back(&mut self) -> Option<L::Item> {
324        either!(*self, ref mut inner => inner.next_back())
325    }
326}
327
328impl<L, R> ExactSizeIterator for Either<L, R>
329    where L: ExactSizeIterator, R: ExactSizeIterator<Item=L::Item>
330{
331}
332
333#[cfg(any(test, feature = "use_std"))]
334/// `Either<L, R>` implements `Read` if both `L` and `R` do.
335///
336/// Requires crate feature `"use_std"`
337impl<L, R> Read for Either<L, R>
338    where L: Read, R: Read
339{
340    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
341        either!(*self, ref mut inner => inner.read(buf))
342    }
343
344    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
345        either!(*self, ref mut inner => inner.read_to_end(buf))
346    }
347}
348
349#[cfg(any(test, feature = "use_std"))]
350/// Requires crate feature `"use_std"`
351impl<L, R> BufRead for Either<L, R>
352    where L: BufRead, R: BufRead
353{
354    fn fill_buf(&mut self) -> io::Result<&[u8]> {
355        either!(*self, ref mut inner => inner.fill_buf())
356    }
357
358    fn consume(&mut self, amt: usize) {
359        either!(*self, ref mut inner => inner.consume(amt))
360    }
361}
362
363#[cfg(any(test, feature = "use_std"))]
364/// `Either<L, R>` implements `Write` if both `L` and `R` do.
365///
366/// Requires crate feature `"use_std"`
367impl<L, R> Write for Either<L, R>
368    where L: Write, R: Write
369{
370    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
371        either!(*self, ref mut inner => inner.write(buf))
372    }
373
374    fn flush(&mut self) -> io::Result<()> {
375        either!(*self, ref mut inner => inner.flush())
376    }
377}
378
379impl<L, R, Target> AsRef<Target> for Either<L, R>
380    where L: AsRef<Target>, R: AsRef<Target>
381{
382    fn as_ref(&self) -> &Target {
383        either!(*self, ref inner => inner.as_ref())
384    }
385}
386
387impl<L, R, Target> AsMut<Target> for Either<L, R>
388    where L: AsMut<Target>, R: AsMut<Target>
389{
390    fn as_mut(&mut self) -> &mut Target {
391        either!(*self, ref mut inner => inner.as_mut())
392    }
393}
394
395impl<L, R> Deref for Either<L, R>
396    where L: Deref, R: Deref<Target=L::Target>
397{
398    type Target = L::Target;
399
400    fn deref(&self) -> &Self::Target {
401        either!(*self, ref inner => &*inner)
402    }
403}
404
405impl<L, R> DerefMut for Either<L, R>
406    where L: DerefMut, R: DerefMut<Target=L::Target>
407{
408    fn deref_mut(&mut self) -> &mut Self::Target {
409        either!(*self, ref mut inner => &mut *inner)
410    }
411}
412
413#[cfg(any(test, feature = "use_std"))]
414/// `Either` implements `Error` if *both* `L` and `R` implement it.
415impl<L, R> Error for Either<L, R>
416    where L: Error, R: Error
417{
418    fn description(&self) -> &str {
419        either!(*self, ref inner => inner.description())
420    }
421
422    fn cause(&self) -> Option<&Error> {
423        either!(*self, ref inner => inner.cause())
424    }
425}
426
427impl<L, R> fmt::Display for Either<L, R>
428    where L: fmt::Display, R: fmt::Display
429{
430    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
431        either!(*self, ref inner => inner.fmt(f))
432    }
433}
434
435#[test]
436fn basic() {
437    let mut e = Left(2);
438    let r = Right(2);
439    assert_eq!(e, Left(2));
440    e = r;
441    assert_eq!(e, Right(2));
442    assert_eq!(e.left(), None);
443    assert_eq!(e.right(), Some(2));
444    assert_eq!(e.as_ref().right(), Some(&2));
445    assert_eq!(e.as_mut().right(), Some(&mut 2));
446}
447
448#[test]
449fn macros() {
450    fn a() -> Either<u32, u32> {
451        let x: u32 = try_left!(Right(1337u32));
452        Left(x * 2)
453    }
454    assert_eq!(a(), Right(1337));
455
456    fn b() -> Either<String, &'static str> {
457        Right(try_right!(Left("foo bar")))
458    }
459    assert_eq!(b(), Left(String::from("foo bar")));
460}
461
462#[test]
463fn deref() {
464    fn is_str(_: &str) {}
465    let value: Either<String, &str> = Left(String::from("test"));
466    is_str(&*value);
467}
468
469#[test]
470fn iter() {
471    let x = 3;
472    let mut iter = match x {
473        1...3 => Left(0..10),
474        _ => Right(17..),
475    };
476
477    assert_eq!(iter.next(), Some(0));
478    assert_eq!(iter.count(), 9);
479}
480
481#[test]
482fn read_write() {
483    use std::io;
484
485    let use_stdio = false;
486    let mockdata = [0xff; 256];
487
488    let mut reader = if use_stdio {
489        Left(io::stdin())
490    } else {
491        Right(&mockdata[..])
492    };
493
494    let mut buf = [0u8; 16];
495    assert_eq!(reader.read(&mut buf).unwrap(), buf.len());
496    assert_eq!(&buf, &mockdata[..buf.len()]);
497
498    let mut mockbuf = [0u8; 256];
499    let mut writer = if use_stdio {
500        Left(io::stdout())
501    } else {
502        Right(&mut mockbuf[..])
503    };
504
505    let buf = [1u8; 16];
506    assert_eq!(writer.write(&buf).unwrap(), buf.len());
507}
508
509#[test]
510fn error() {
511    let invalid_utf8 = b"\xff";
512    let res = || -> Result<_, Either<_, _>> {
513        try!(::std::str::from_utf8(invalid_utf8).map_err(Left));
514        try!("x".parse::<i32>().map_err(Right));
515        Ok(())
516    }();
517    assert!(res.is_err());
518    res.unwrap_err().description(); // make sure this can be called
519}