(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>>>(eithers: Iter)
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>>>(eithers: Iter)
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> {