(index<- )        ./libstd/either.rs

   1  // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
   2  // file at the top-level directory of this distribution and at
   3  // http://rust-lang.org/COPYRIGHT.
   4  //
   5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
   6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
   7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
   8  // option. This file may not be copied, modified, or distributed
   9  // except according to those terms.
  10  
  11  //! A type that represents one of two alternatives
  12  
  13  #[allow(missing_doc)];
  14  
  15  use option::{Some, None};
  16  use option;
  17  use clone::Clone;
  18  use container::Container;
  19  use cmp::Eq;
  20  use iter::{Iterator, FilterMap};
  21  use result::Result;
  22  use result;
  23  use str::StrSlice;
  24  use vec;
  25  use vec::{OwnedVector, ImmutableVector};
  26  
  27  /// `Either` is a type that represents one of two alternatives
  28  #[deriving(Clone, Eq, IterBytes)]
  29  pub enum Either<L, R> {
  30      Left(L),
  31      Right(R)
  32  }
  33  
  34  impl<L, R> Either<L, R> {
  35      /// Applies a function based on the given either value
  36      ///
  37      /// If `value` is `Left(L)` then `f_left` is applied to its contents, if
  38      /// `value` is `Right(R)` then `f_right` is applied to its contents, and the
  39      /// result is returned.
  40      #[inline]
  41      pub fn either<T>(&self, f_left&fn(&L) -> T, f_right&fn(&R) -> T) -> T {
  42          match *self {
  43              Left(ref l) => f_left(l),
  44              Right(ref r) => f_right(r)
  45          }
  46      }
  47  
  48      /// Flips between left and right of a given `Either`
  49      #[inline]
  50      pub fn flip(self) -> Either<R, L> {
  51          match self {
  52              Right(r) => Left(r),
  53              Left(l) => Right(l)
  54          }
  55      }
  56  
  57      /// Checks whether the given value is a `Left`
  58      #[inline]
  59      pub fn is_left(&self) -> bool {
  60          match *self {
  61              Left(_) => true,
  62              _ => false
  63          }
  64      }
  65  
  66      /// Checks whether the given value is a `Right`
  67      #[inline]
  68      pub fn is_right(&self) -> bool {
  69          match *self {
  70              Right(_) => true,
  71              _ => false
  72          }
  73      }
  74  
  75      /// Retrieves the value from a `Left`.
  76      /// Fails with a specified reason if the `Either` is `Right`.
  77      #[inline]
  78      pub fn expect_left(self, reason&str) -> L {
  79          match self {
  80              Left(x) => x,
  81              Right(_) => fail2!("{}", reason.to_owned())
  82          }
  83      }
  84  
  85      /// Retrieves the value from a `Left`. Fails if the `Either` is `Right`.
  86      #[inline]
  87      pub fn unwrap_left(self) -> L {
  88          self.expect_left("called Either::unwrap_left()` on `Right` value")
  89      }
  90  
  91      /// Retrieves the value from a `Right`.
  92      /// Fails with a specified reason if the `Either` is `Left`.
  93      #[inline]
  94      pub fn expect_right(self, reason&str) -> R {
  95          match self {
  96              Right(x) => x,
  97              Left(_) => fail2!("{}", reason.to_owned())
  98          }
  99      }
 100  
 101      /// Retrieves the value from a `Right`. Fails if the `Either` is `Left`.
 102      #[inline]
 103      pub fn unwrap_right(self) -> R {
 104          self.expect_right("called Either::unwrap_right()` on `Left` value")
 105      }
 106  }
 107  
 108  /// A generic trait for converting a value to a `Either`
 109  pub trait ToEither<L, R> {
 110      /// Convert to the `either` type
 111      fn to_either(&self) -> Either<L, R>;
 112  }
 113  
 114  /// A generic trait for converting a value to a `Either`
 115  pub trait IntoEither<L, R> {
 116      /// Convert to the `either` type
 117      fn into_either(self) -> Either<L, R>;
 118  }
 119  
 120  /// A generic trait for converting a value to a `Either`
 121  pub trait AsEither<L, R> {
 122      /// Convert to the `either` type
 123      fn as_either<'a>(&'a self) -> Either<&'a L, &'a R>;
 124  }
 125  
 126  impl<L, R: Clone> option::ToOption<R> for Either<L, R> {
 127      #[inline]
 128      fn to_option(&self)-> option::Option<R> {
 129          match *self {
 130              Left(_) => None,
 131              Right(ref r) => Some(r.clone()),
 132          }
 133      }
 134  }
 135  
 136  impl<L, R> option::IntoOption<R> for Either<L, R> {
 137      #[inline]
 138      fn into_option(self)-> option::Option<R> {
 139          match self {
 140              Left(_) => None,
 141              Right(r) => Some(r),
 142          }
 143      }
 144  }
 145  
 146  impl<L, R> option::AsOption<R> for Either<L, R> {
 147      #[inline]
 148      fn as_option<'a>(&'a self) -> option::Option<&'a R> {
 149          match *self {
 150              Left(_) => None,
 151              Right(ref r) => Some(r),
 152          }
 153      }
 154  }
 155  
 156  impl<L: Clone, R: Clone> result::ToResult<R, L> for Either<L, R> {
 157      #[inline]
 158      fn to_result(&self)-> result::Result<R, L> {
 159          match *self {
 160              Left(ref l) => result::Err(l.clone()),
 161              Right(ref r) => result::Ok(r.clone()),
 162          }
 163      }
 164  }
 165  
 166  impl<L, R> result::IntoResult<R, L> for Either<L, R> {
 167      #[inline]
 168      fn into_result(self)-> result::Result<R, L> {
 169          match self {
 170              Left(l) => result::Err(l),
 171              Right(r) => result::Ok(r),
 172          }
 173      }
 174  }
 175  
 176  impl<L, R> result::AsResult<R, L> for Either<L, R> {
 177      #[inline]
 178      fn as_result<'a>(&'a self) -> result::Result<&'a R, &'a L> {
 179          match *self {
 180              Left(ref l) => result::Err(l),
 181              Right(ref r) => result::Ok(r),
 182          }
 183      }
 184  }
 185  
 186  impl<L: Clone, R: Clone> ToEither<L, R> for Either<L, R> {
 187      fn to_either(&self) -> Either<L, R> { self.clone() }
 188  }
 189  
 190  impl<L, R> IntoEither<L, R> for Either<L, R> {
 191      fn into_either(self) -> Either<L, R> { self }
 192  }
 193  
 194  impl<L, R> AsEither<L, R> for Either<L, R> {
 195      fn as_either<'a>(&'a self) -> Either<&'a L, &'a R> {
 196          match *self {
 197              Left(ref l) => Left(l),
 198              Right(ref r) => Right(r),
 199          }
 200      }
 201  }
 202  
 203  /// An iterator yielding the `Left` values of its source
 204  pub type Lefts<L, R, Iter> = FilterMap<'static, Either<L, R>, L, Iter>;
 205  
 206  /// An iterator yielding the `Right` values of its source
 207  pub type Rights<L, R, Iter> = FilterMap<'static, Either<L, R>, R, Iter>;
 208  
 209  /// Extracts all the left values
 210  pub fn lefts<L, R, Iter: Iterator<Either<L, R>>>(eithersIter)
 211      -> Lefts<L, R, Iter> {
 212      do eithers.filter_map |elt| {
 213          match elt {
 214              Left(x) => Some(x),
 215              _ => None,
 216          }
 217      }
 218  }
 219  
 220  /// Extracts all the right values
 221  pub fn rights<L, R, Iter: Iterator<Either<L, R>>>(eithersIter)
 222      -> Rights<L, R, Iter> {
 223      do eithers.filter_map |elt| {
 224          match elt {
 225              Right(x) => Some(x),
 226              _ => None,
 227          }
 228      }
 229  }
 230  
 231  
 232  // FIXME: #8228 Replaceable by an external iterator?
 233  /// Extracts from a vector of either all the left values and right values
 234  ///
 235  /// Returns a structure containing a vector of left values and a vector of
 236  /// right values.
 237  pub fn partition<L, R>(eithers~[Either<L, R>]) -> (~[L], ~[R]) {
 238      let n_lefts = eithers.iter().count(|elt| elt.is_left());
 239      let mut lefts = vec::with_capacity(n_lefts);
 240      let mut rights = vec::with_capacity(eithers.len() - n_lefts);
 241      for elt in eithers.move_iter() {
 242          match elt {
 243              Left(l) => lefts.push(l),
 244              Right(r) => rights.push(r)
 245          }
 246      }
 247      return (lefts, rights);
 248  }
 249  
 250  #[cfg(test)]
 251  mod tests {
 252      use super::*;
 253  
 254      use option::{IntoOption, ToOption, AsOption};
 255      use option;
 256      use result::{IntoResult, ToResult, AsResult};
 257      use result;
 258  
 259      #[test]
 260      fn test_either_left() {
 261          let val = Left(10);
 262          fn f_left(x: &int) -> bool { *x == 10 }
 263          fn f_right(_x: &uint) -> bool { false }
 264          assert!(val.either(f_left, f_right));
 265      }
 266  
 267      #[test]
 268      fn test_either_right() {
 269          let val = Right(10u);
 270          fn f_left(_x: &int) -> bool { false }
 271          fn f_right(x: &uint) -> bool { *x == 10u }
 272          assert!(val.either(f_left, f_right));
 273      }
 274  
 275      #[test]
 276      fn test_lefts() {
 277          let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
 278          let result = lefts(input.move_iter()).to_owned_vec();
 279          assert_eq!(result, ~[10, 12, 14]);
 280      }
 281  
 282      #[test]
 283      fn test_lefts_none() {
 284          let input: ~[Either<int, int>] = ~[Right(10), Right(10)];
 285          let result = lefts(input.move_iter()).to_owned_vec();
 286          assert_eq!(result.len(), 0u);
 287      }
 288  
 289      #[test]
 290      fn test_lefts_empty() {
 291          let input: ~[Either<int, int>] = ~[];
 292          let result = lefts(input.move_iter()).to_owned_vec();
 293          assert_eq!(result.len(), 0u);
 294      }
 295  
 296      #[test]
 297      fn test_rights() {
 298          let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
 299          let result = rights(input.move_iter()).to_owned_vec();
 300          assert_eq!(result, ~[11, 13]);
 301      }
 302  
 303      #[test]
 304      fn test_rights_none() {
 305          let input: ~[Either<int, int>] = ~[Left(10), Left(10)];
 306          let result = rights(input.move_iter()).to_owned_vec();
 307          assert_eq!(result.len(), 0u);
 308      }
 309  
 310      #[test]
 311      fn test_rights_empty() {
 312          let input: ~[Either<int, int>] = ~[];
 313          let result = rights(input.move_iter()).to_owned_vec();
 314          assert_eq!(result.len(), 0u);
 315      }
 316  
 317      #[test]
 318      fn test_partition() {
 319          let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
 320          let (lefts, rights) = partition(input);
 321          assert_eq!(lefts[0], 10);
 322          assert_eq!(lefts[1], 12);
 323          assert_eq!(lefts[2], 14);
 324          assert_eq!(rights[0], 11);
 325          assert_eq!(rights[1], 13);
 326      }
 327  
 328      #[test]
 329      fn test_partition_no_lefts() {
 330          let input: ~[Either<int, int>] = ~[Right(10), Right(11)];
 331          let (lefts, rights) = partition(input);
 332          assert_eq!(lefts.len(), 0u);
 333          assert_eq!(rights.len(), 2u);
 334      }
 335  
 336      #[test]
 337      fn test_partition_no_rights() {
 338          let input: ~[Either<int, int>] = ~[Left(10), Left(11)];
 339          let (lefts, rights) = partition(input);
 340          assert_eq!(lefts.len(), 2u);
 341          assert_eq!(rights.len(), 0u);
 342      }
 343  
 344      #[test]
 345      fn test_partition_empty() {
 346          let input: ~[Either<int, int>] = ~[];
 347          let (lefts, rights) = partition(input);
 348          assert_eq!(lefts.len(), 0u);
 349          assert_eq!(rights.len(), 0u);
 350      }
 351  
 352      #[test]
 353      pub fn test_to_option() {
 354          let right: Either<int, int> = Right(100);
 355          let left: Either<int, int> = Left(404);
 356  
 357          assert_eq!(right.to_option(), option::Some(100));
 358          assert_eq!(left.to_option(), option::None);
 359      }
 360  
 361      #[test]
 362      pub fn test_into_option() {
 363          let right: Either<int, int> = Right(100);
 364          let left: Either<int, int> = Left(404);
 365  
 366          assert_eq!(right.into_option(), option::Some(100));
 367          assert_eq!(left.into_option(), option::None);
 368      }
 369  
 370      #[test]
 371      pub fn test_as_option() {
 372          let right: Either<int, int> = Right(100);
 373          let left: Either<int, int> = Left(404);
 374  
 375          assert_eq!(right.as_option().unwrap(), &100);
 376          assert_eq!(left.as_option(), option::None);
 377      }
 378  
 379      #[test]
 380      pub fn test_to_result() {
 381          let right: Either<int, int> = Right(100);
 382          let left: Either<int, int> = Left(404);
 383  
 384          assert_eq!(right.to_result(), result::Ok(100));
 385          assert_eq!(left.to_result(), result::Err(404));
 386      }
 387  
 388      #[test]
 389      pub fn test_into_result() {
 390          let right: Either<int, int> = Right(100);
 391          let left: Either<int, int> = Left(404);
 392  
 393          assert_eq!(right.into_result(), result::Ok(100));
 394          assert_eq!(left.into_result(), result::Err(404));
 395      }
 396  
 397      #[test]
 398      pub fn test_as_result() {
 399          let right: Either<int, int> = Right(100);
 400          let left: Either<int, int> = Left(404);
 401  
 402          let x = 100;
 403          assert_eq!(right.as_result(), result::Ok(&x));
 404  
 405          let x = 404;
 406          assert_eq!(left.as_result(), result::Err(&x));
 407      }
 408  
 409      #[test]
 410      pub fn test_to_either() {
 411          let right: Either<int, int> = Right(100);
 412          let left: Either<int, int> = Left(404);
 413  
 414          assert_eq!(right.to_either(), Right(100));
 415          assert_eq!(left.to_either(), Left(404));
 416      }
 417  
 418      #[test]
 419      pub fn test_into_either() {
 420          let right: Either<int, int> = Right(100);
 421          let left: Either<int, int> = Left(404);
 422  
 423          assert_eq!(right.into_either(), Right(100));
 424          assert_eq!(left.into_either(), Left(404));
 425      }
 426  
 427      #[test]
 428      pub fn test_as_either() {
 429          let right: Either<int, int> = Right(100);
 430          let left: Either<int, int> = Left(404);
 431  
 432          assert_eq!(right.as_either().unwrap_right(), &100);
 433          assert_eq!(left.as_either().unwrap_left(), &404);
 434      }
 435  }

libstd/either.rs:108:57-108:57 -trait- definition:
/// A generic trait for converting a value to a `Either`
pub trait ToEither<L, R> {
references:-
186: impl<L: Clone, R: Clone> ToEither<L, R> for Either<L, R> {
libstd/option.rs:
407: impl<T: Clone> either::ToEither<(), T> for Option<T> {
libstd/result.rs:
342: impl<T: Clone, E: Clone> either::ToEither<E, T> for Result<T, E> {


libstd/either.rs:28:34-28:34 -enum- definition:
#[deriving(Clone, Eq, IterBytes)]
pub enum Either<L, R> {
references:-
237: pub fn partition<L, R>(eithers: ~[Either<L, R>]) -> (~[L], ~[R]) {
221: pub fn rights<L, R, Iter: Iterator<Either<L, R>>>(eithers: Iter)
190: impl<L, R> IntoEither<L, R> for Either<L, R> {
28: #[deriving(Clone, Eq, IterBytes)]
111:     fn to_either(&self) -> Either<L, R>;
50:     pub fn flip(self) -> Either<R, L> {
28: #[deriving(Clone, Eq, IterBytes)]
28: #[deriving(Clone, Eq, IterBytes)]
186: impl<L: Clone, R: Clone> ToEither<L, R> for Either<L, R> {
146: impl<L, R> option::AsOption<R> for Either<L, R> {
176: impl<L, R> result::AsResult<R, L> for Either<L, R> {
194: impl<L, R> AsEither<L, R> for Either<L, R> {
207: pub type Rights<L, R, Iter> = FilterMap<'static, Either<L, R>, R, Iter>;
28: #[deriving(Clone, Eq, IterBytes)]
204: pub type Lefts<L, R, Iter> = FilterMap<'static, Either<L, R>, L, Iter>;
156: impl<L: Clone, R: Clone> result::ToResult<R, L> for Either<L, R> {
210: pub fn lefts<L, R, Iter: Iterator<Either<L, R>>>(eithers: Iter)
123:     fn as_either<'a>(&'a self) -> Either<&'a L, &'a R>;
34: impl<L, R> Either<L, R> {
187:     fn to_either(&self) -> Either<L, R> { self.clone() }
195:     fn as_either<'a>(&'a self) -> Either<&'a L, &'a R> {
191:     fn into_either(self) -> Either<L, R> { self }
166: impl<L, R> result::IntoResult<R, L> for Either<L, R> {
126: impl<L, R: Clone> option::ToOption<R> for Either<L, R> {
136: impl<L, R> option::IntoOption<R> for Either<L, R> {
28: #[deriving(Clone, Eq, IterBytes)]
28: #[deriving(Clone, Eq, IterBytes)]
117:     fn into_either(self) -> Either<L, R>;
libstd/fmt/parse.rs:
130:     selector: Either<PluralKeyword, uint>,
libstd/fmt/rt.rs:
59:     selector: Either<parse::PluralKeyword, uint>,
libstd/unstable/sync.rs:
(183)
libstd/rt/kill.rs:
(279)
libstd/option.rs:
(409)(419)
libstd/result.rs:
(364)(344)(354)

libstd/either.rs:203:57-203:57 -ty- definition:
/// An iterator yielding the `Left` values of its source
pub type Lefts<L, R, Iter> = FilterMap<'static, Either<L, R>, L, Iter>;
references:-
211:     -> Lefts<L, R, Iter> {


libstd/either.rs:206:58-206:58 -ty- definition:
/// An iterator yielding the `Right` values of its source
pub type Rights<L, R, Iter> = FilterMap<'static, Either<L, R>, R, Iter>;
references:-
222:     -> Rights<L, R, Iter> {


libstd/either.rs:120:57-120:57 -trait- definition:
/// A generic trait for converting a value to a `Either`
pub trait AsEither<L, R> {
references:-
194: impl<L, R> AsEither<L, R> for Either<L, R> {
libstd/result.rs:
362: impl<T, E> either::AsEither<E, T> for Result<T, E> {


libstd/either.rs:114:57-114:57 -trait- definition:
/// A generic trait for converting a value to a `Either`
pub trait IntoEither<L, R> {
references:-
190: impl<L, R> IntoEither<L, R> for Either<L, R> {
libstd/option.rs:
417: impl<T> either::IntoEither<(), T> for Option<T> {
libstd/result.rs:
352: impl<T, E> either::IntoEither<E, T> for Result<T, E> {