1#![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#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
31pub enum Either<L, R> {
32 Left(L),
34 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_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#[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 pub fn is_left(&self) -> bool {
102 match *self {
103 Left(_) => true,
104 Right(_) => false,
105 }
106 }
107
108 pub fn is_right(&self) -> bool {
118 !self.is_left()
119 }
120
121 pub fn left(self) -> Option<L> {
133 match self {
134 Left(l) => Some(l),
135 Right(_) => None,
136 }
137 }
138
139 pub fn right(self) -> Option<R> {
151 match self {
152 Left(_) => None,
153 Right(r) => Some(r),
154 }
155 }
156
157 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 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 pub fn flip(self) -> Either<R, L> {
212 match self {
213 Left(l) => Right(l),
214 Right(r) => Left(r),
215 }
216 }
217
218 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 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 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
285impl<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
295impl<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
305impl<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"))]
334impl<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"))]
350impl<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"))]
364impl<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"))]
414impl<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(); }