]> git.lizzy.rs Git - rust.git/blob - src/libstd/result.rs
auto merge of #10519 : nikomatsakis/rust/issue-8624-borrowck-overly-permissive, r...
[rust.git] / src / libstd / result.rs
1 // Copyright 2012-2013 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 representing either success or failure
12
13 use any::Any;
14 use clone::Clone;
15 use cmp::Eq;
16 use fmt;
17 use iter::Iterator;
18 use kinds::Send;
19 use option::{None, Option, Some, OptionIterator};
20 use option::{ToOption, IntoOption, AsOption};
21 use str::OwnedStr;
22 use to_str::ToStr;
23 use vec::OwnedVector;
24 use vec;
25
26 /// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
27 ///
28 /// In order to provide informative error messages, `E` is required to implement `ToStr`.
29 /// It is further recommended for `E` to be a descriptive error type, eg a `enum` for
30 /// all possible errors cases.
31 #[deriving(Clone, DeepClone, Eq, Ord, TotalEq, TotalOrd, ToStr)]
32 pub enum Result<T, E> {
33     /// Contains the successful result value
34     Ok(T),
35     /// Contains the error value
36     Err(E)
37 }
38
39 /////////////////////////////////////////////////////////////////////////////
40 // Type implementation
41 /////////////////////////////////////////////////////////////////////////////
42
43 impl<T, E: ToStr> Result<T, E> {
44     /////////////////////////////////////////////////////////////////////////
45     // Querying the contained values
46     /////////////////////////////////////////////////////////////////////////
47
48     /// Returns true if the result is `Ok`
49     #[inline]
50     pub fn is_ok(&self) -> bool {
51         match *self {
52             Ok(_) => true,
53             Err(_) => false
54         }
55     }
56
57     /// Returns true if the result is `Err`
58     #[inline]
59     pub fn is_err(&self) -> bool {
60         !self.is_ok()
61     }
62
63     /////////////////////////////////////////////////////////////////////////
64     // Adapter for working with references
65     /////////////////////////////////////////////////////////////////////////
66
67     /// Convert from `Result<T, E>` to `Result<&T, &E>`
68     #[inline]
69     pub fn as_ref<'r>(&'r self) -> Result<&'r T, &'r E> {
70         match *self {
71             Ok(ref x) => Ok(x),
72             Err(ref x) => Err(x),
73         }
74     }
75
76     /// Convert from `Result<T, E>` to `Result<&mut T, &mut E>`
77     #[inline]
78     pub fn as_mut<'r>(&'r mut self) -> Result<&'r mut T, &'r mut E> {
79         match *self {
80             Ok(ref mut x) => Ok(x),
81             Err(ref mut x) => Err(x),
82         }
83     }
84
85     /////////////////////////////////////////////////////////////////////////
86     // Getting to contained values
87     /////////////////////////////////////////////////////////////////////////
88
89     /// Unwraps a result, yielding the content of an `Ok`.
90     /// Fails if the value is a `Err` with a custom failure message provided by `msg`.
91     #[inline]
92     pub fn expect<M: Any + Send>(self, msg: M) -> T {
93         match self {
94             Ok(t) => t,
95             Err(_) => fail!(msg),
96         }
97     }
98
99     /// Unwraps a result, yielding the content of an `Err`.
100     /// Fails if the value is a `Ok` with a custom failure message provided by `msg`.
101     #[inline]
102     pub fn expect_err<M: Any + Send>(self, msg: M) -> E {
103         match self {
104             Err(e) => e,
105             Ok(_) => fail!(msg),
106         }
107     }
108
109     /// Unwraps a result, yielding the content of an `Ok`.
110     /// Fails if the value is a `Err` with an error message derived
111     /// from `E`'s `ToStr` implementation.
112     #[inline]
113     pub fn unwrap(self) -> T {
114         match self {
115             Ok(t) => t,
116             Err(e) => fail!("called `Result::unwrap()` on `Err` value '{}'",
117                              e.to_str()),
118         }
119     }
120
121     /// Unwraps a result, yielding the content of an `Err`.
122     /// Fails if the value is a `Ok`.
123     #[inline]
124     pub fn unwrap_err(self) -> E {
125         match self {
126             Ok(_) => fail!("called `Result::unwrap_err()` on an `Ok` value"),
127             Err(e) => e
128         }
129     }
130
131     /////////////////////////////////////////////////////////////////////////
132     // Transforming contained values
133     /////////////////////////////////////////////////////////////////////////
134
135     /// Maps an `Result<T, E>` to `Result<U, E>` by applying a function to an
136     /// contained `Ok` value, leaving an `Err` value untouched.
137     ///
138     /// This function can be used to compose the results of two functions.
139     ///
140     /// Example:
141     ///
142     ///     let res = read_file(file).map(|buf| {
143     ///         parse_bytes(buf)
144     ///     })
145     #[inline]
146     pub fn map<U>(self, op: |T| -> U) -> Result<U,E> {
147         match self {
148           Ok(t) => Ok(op(t)),
149           Err(e) => Err(e)
150         }
151     }
152
153     /// Maps an `Result<T, E>` to `Result<T, F>` by applying a function to an
154     /// contained `Err` value, leaving an `Ok` value untouched.
155     ///
156     /// This function can be used to pass through a successful result while handling
157     /// an error.
158     #[inline]
159     pub fn map_err<F>(self, op: |E| -> F) -> Result<T,F> {
160         match self {
161           Ok(t) => Ok(t),
162           Err(e) => Err(op(e))
163         }
164     }
165
166     /////////////////////////////////////////////////////////////////////////
167     // Iterator constructors
168     /////////////////////////////////////////////////////////////////////////
169
170     /// Returns an `Iterator` over one or zero references to the value of an `Ok`
171     ///
172     /// Example:
173     ///
174     ///     for buf in read_file(file) {
175     ///         print_buf(buf)
176     ///     }
177     #[inline]
178     pub fn iter<'r>(&'r self) -> OptionIterator<&'r T> {
179         match *self {
180             Ok(ref t) => Some(t),
181             Err(*) => None,
182         }.move_iter()
183     }
184
185     /// Returns an `Iterator` over one or zero references to the value of an `Err`
186     #[inline]
187     pub fn iter_err<'r>(&'r self) -> OptionIterator<&'r E> {
188         match *self {
189             Ok(*) => None,
190             Err(ref t) => Some(t),
191         }.move_iter()
192     }
193
194     ////////////////////////////////////////////////////////////////////////
195     // Boolean operations on the values, eager and lazy
196     /////////////////////////////////////////////////////////////////////////
197
198     /// Returns `res` if the result is `Ok`, otherwise returns the `Err` value of `self`.
199     #[inline]
200     pub fn and<U>(self, res: Result<U, E>) -> Result<U, E> {
201         match self {
202             Ok(_) => res,
203             Err(e) => Err(e),
204         }
205     }
206
207     /// Calls `op` if the result is `Ok`, otherwise returns the `Err` value of `self`.
208     ///
209     /// This function can be used for control flow based on result values
210     #[inline]
211     pub fn and_then<U>(self, op: |T| -> Result<U, E>) -> Result<U, E> {
212         match self {
213             Ok(t) => op(t),
214             Err(e) => Err(e),
215         }
216     }
217
218     /// Returns `res` if the result is `Err`, otherwise returns the `Ok` value of `self`.
219     #[inline]
220     pub fn or(self, res: Result<T, E>) -> Result<T, E> {
221         match self {
222             Ok(_) => self,
223             Err(_) => res,
224         }
225     }
226
227     /// Calls `op` if the result is `Err`, otherwise returns the `Ok` value of `self`.
228     ///
229     /// This function can be used for control flow based on result values
230     #[inline]
231     pub fn or_else<F>(self, op: |E| -> Result<T, F>) -> Result<T, F> {
232         match self {
233             Ok(t) => Ok(t),
234             Err(e) => op(e),
235         }
236     }
237
238     /////////////////////////////////////////////////////////////////////////
239     // Common special cases
240     /////////////////////////////////////////////////////////////////////////
241
242     /// Get a reference to the value out of a successful result
243     ///
244     /// # Failure
245     ///
246     /// If the result is an error
247     #[inline]
248     pub fn get_ref<'a>(&'a self) -> &'a T {
249         match *self {
250             Ok(ref t) => t,
251             Err(ref e) => fail!("called `Result::get_ref()` on `Err` value '{}'",
252                                  e.to_str()),
253         }
254     }
255 }
256
257 /////////////////////////////////////////////////////////////////////////////
258 // Constructor extension trait
259 /////////////////////////////////////////////////////////////////////////////
260
261 /// A generic trait for converting a value to a `Result`
262 pub trait ToResult<T, E> {
263     /// Convert to the `result` type
264     fn to_result(&self) -> Result<T, E>;
265 }
266
267 /// A generic trait for converting a value to a `Result`
268 pub trait IntoResult<T, E> {
269     /// Convert to the `result` type
270     fn into_result(self) -> Result<T, E>;
271 }
272
273 /// A generic trait for converting a value to a `Result`
274 pub trait AsResult<T, E> {
275     /// Convert to the `result` type
276     fn as_result<'a>(&'a self) -> Result<&'a T, &'a E>;
277 }
278
279 impl<T: Clone, E: Clone> ToResult<T, E> for Result<T, E> {
280     #[inline]
281     fn to_result(&self) -> Result<T, E> { self.clone() }
282 }
283
284 impl<T, E> IntoResult<T, E> for Result<T, E> {
285     #[inline]
286     fn into_result(self) -> Result<T, E> { self }
287 }
288
289 impl<T, E> AsResult<T, E> for Result<T, E> {
290     #[inline]
291     fn as_result<'a>(&'a self) -> Result<&'a T, &'a E> {
292         match *self {
293             Ok(ref t) => Ok(t),
294             Err(ref e) => Err(e),
295         }
296     }
297 }
298
299 /////////////////////////////////////////////////////////////////////////////
300 // Trait implementations
301 /////////////////////////////////////////////////////////////////////////////
302
303 impl<T: Clone, E> ToOption<T> for Result<T, E> {
304     #[inline]
305     fn to_option(&self) -> Option<T> {
306         match *self {
307             Ok(ref t) => Some(t.clone()),
308             Err(_) => None,
309         }
310     }
311 }
312
313 impl<T, E> IntoOption<T> for Result<T, E> {
314     #[inline]
315     fn into_option(self) -> Option<T> {
316         match self {
317             Ok(t) => Some(t),
318             Err(_) => None,
319         }
320     }
321 }
322
323 impl<T, E> AsOption<T> for Result<T, E> {
324     #[inline]
325     fn as_option<'a>(&'a self) -> Option<&'a T> {
326         match *self {
327             Ok(ref t) => Some(t),
328             Err(_) => None,
329         }
330     }
331 }
332
333 impl<T: fmt::Default, E: fmt::Default> fmt::Default for Result<T, E> {
334     #[inline]
335     fn fmt(s: &Result<T, E>, f: &mut fmt::Formatter) {
336         match *s {
337             Ok(ref t) => write!(f.buf, "Ok({})", *t),
338             Err(ref e) => write!(f.buf, "Err({})", *e)
339         }
340     }
341 }
342
343 /////////////////////////////////////////////////////////////////////////////
344 // Free functions
345 /////////////////////////////////////////////////////////////////////////////
346
347 /// Takes each element in the iterator: if it is an error, no further
348 /// elements are taken, and the error is returned.
349 /// Should no error occur, a vector containing the values of each Result
350 /// is returned.
351 ///
352 /// Here is an example which increments every integer in a vector,
353 /// checking for overflow:
354 ///
355 ///     fn inc_conditionally(x: uint) -> Result<uint, &'static str> {
356 ///         if x == uint::max_value { return Err("overflow"); }
357 ///         else { return Ok(x+1u); }
358 ///     }
359 ///     let v = [1u, 2, 3];
360 ///     let res = collect(v.iter().map(|&x| inc_conditionally(x)));
361 ///     assert!(res == Ok(~[2u, 3, 4]));
362 #[inline]
363 pub fn collect<T, E, Iter: Iterator<Result<T, E>>>(mut iterator: Iter)
364     -> Result<~[T], E> {
365     let (lower, _) = iterator.size_hint();
366     let mut vs: ~[T] = vec::with_capacity(lower);
367     for t in iterator {
368         match t {
369             Ok(v) => vs.push(v),
370             Err(u) => return Err(u)
371         }
372     }
373     Ok(vs)
374 }
375
376 /// Perform a fold operation over the result values from an iterator.
377 ///
378 /// If an `Err` is encountered, it is immediately returned.
379 /// Otherwise, the folded value is returned.
380 #[inline]
381 pub fn fold<T,
382             V,
383             E,
384             Iter: Iterator<Result<T, E>>>(
385             mut iterator: Iter,
386             mut init: V,
387             f: |V, T| -> V)
388             -> Result<V, E> {
389     for t in iterator {
390         match t {
391             Ok(v) => init = f(init, v),
392             Err(u) => return Err(u)
393         }
394     }
395     Ok(init)
396 }
397
398 /// Perform a trivial fold operation over the result values
399 /// from an iterator.
400 ///
401 /// If an `Err` is encountered, it is immediately returned.
402 /// Otherwise, a simple `Ok(())` is returned.
403 #[inline]
404 pub fn fold_<T,E,Iter:Iterator<Result<T,E>>>(iterator: Iter) -> Result<(),E> {
405     fold(iterator, (), |_, _| ())
406 }
407
408 /////////////////////////////////////////////////////////////////////////////
409 // Tests
410 /////////////////////////////////////////////////////////////////////////////
411
412 #[cfg(test)]
413 mod tests {
414     use super::*;
415
416     use iter::range;
417     use option::{IntoOption, ToOption, AsOption};
418     use option::{Some, None};
419     use vec::ImmutableVector;
420     use to_str::ToStr;
421
422     pub fn op1() -> Result<int, ~str> { Ok(666) }
423     pub fn op2() -> Result<int, ~str> { Err(~"sadface") }
424
425     #[test]
426     pub fn test_and() {
427         assert_eq!(op1().and(Ok(667)).unwrap(), 667);
428         assert_eq!(op1().and(Err::<(), ~str>(~"bad")).unwrap_err(), ~"bad");
429
430         assert_eq!(op2().and(Ok(667)).unwrap_err(), ~"sadface");
431         assert_eq!(op2().and(Err::<(), ~str>(~"bad")).unwrap_err(), ~"sadface");
432     }
433
434     #[test]
435     pub fn test_and_then() {
436         assert_eq!(op1().and_then(|i| Ok::<int, ~str>(i + 1)).unwrap(), 667);
437         assert_eq!(op1().and_then(|_| Err::<int, ~str>(~"bad")).unwrap_err(), ~"bad");
438
439         assert_eq!(op2().and_then(|i| Ok::<int, ~str>(i + 1)).unwrap_err(), ~"sadface");
440         assert_eq!(op2().and_then(|_| Err::<int, ~str>(~"bad")).unwrap_err(), ~"sadface");
441     }
442
443     #[test]
444     pub fn test_or() {
445         assert_eq!(op1().or(Ok(667)).unwrap(), 666);
446         assert_eq!(op1().or(Err(~"bad")).unwrap(), 666);
447
448         assert_eq!(op2().or(Ok(667)).unwrap(), 667);
449         assert_eq!(op2().or(Err(~"bad")).unwrap_err(), ~"bad");
450     }
451
452     #[test]
453     pub fn test_or_else() {
454         assert_eq!(op1().or_else(|_| Ok::<int, ~str>(667)).unwrap(), 666);
455         assert_eq!(op1().or_else(|e| Err::<int, ~str>(e + "!")).unwrap(), 666);
456
457         assert_eq!(op2().or_else(|_| Ok::<int, ~str>(667)).unwrap(), 667);
458         assert_eq!(op2().or_else(|e| Err::<int, ~str>(e + "!")).unwrap_err(), ~"sadface!");
459     }
460
461     #[test]
462     pub fn test_impl_iter() {
463         let mut valid = false;
464         let okval = Ok::<~str, ~str>(~"a");
465         okval.iter().next().map(|_| { valid = true; });
466         assert!(valid);
467
468         let errval = Err::<~str, ~str>(~"b");
469         errval.iter().next().map(|_| { valid = false; });
470         assert!(valid);
471     }
472
473     #[test]
474     pub fn test_impl_iter_err() {
475         let mut valid = true;
476         let okval = Ok::<~str, ~str>(~"a");
477         okval.iter_err().next().map(|_| { valid = false });
478         assert!(valid);
479
480         valid = false;
481         let errval = Err::<~str, ~str>(~"b");
482         errval.iter_err().next().map(|_| { valid = true });
483         assert!(valid);
484     }
485
486     #[test]
487     pub fn test_impl_map() {
488         assert_eq!(Ok::<~str, ~str>(~"a").map(|x| x + "b"), Ok(~"ab"));
489         assert_eq!(Err::<~str, ~str>(~"a").map(|x| x + "b"), Err(~"a"));
490     }
491
492     #[test]
493     pub fn test_impl_map_err() {
494         assert_eq!(Ok::<~str, ~str>(~"a").map_err(|x| x + "b"), Ok(~"a"));
495         assert_eq!(Err::<~str, ~str>(~"a").map_err(|x| x + "b"), Err(~"ab"));
496     }
497
498     #[test]
499     pub fn test_get_ref_method() {
500         let foo: Result<int, ()> = Ok(100);
501         assert_eq!(*foo.get_ref(), 100);
502     }
503
504     #[test]
505     fn test_collect() {
506         assert_eq!(collect(range(0, 0)
507                            .map(|_| Ok::<int, ()>(0))),
508                    Ok(~[]));
509         assert_eq!(collect(range(0, 3)
510                            .map(|x| Ok::<int, ()>(x))),
511                    Ok(~[0, 1, 2]));
512         assert_eq!(collect(range(0, 3)
513                            .map(|x| if x > 1 { Err(x) } else { Ok(x) })),
514                    Err(2));
515
516         // test that it does not take more elements than it needs
517         let functions = [|| Ok(()), || Err(1), || fail!()];
518
519         assert_eq!(collect(functions.iter().map(|f| (*f)())),
520                    Err(1));
521     }
522
523     #[test]
524     fn test_fold() {
525         assert_eq!(fold_(range(0, 0)
526                         .map(|_| Ok::<(), ()>(()))),
527                    Ok(()));
528         assert_eq!(fold(range(0, 3)
529                         .map(|x| Ok::<int, ()>(x)),
530                         0, |a, b| a + b),
531                    Ok(3));
532         assert_eq!(fold_(range(0, 3)
533                         .map(|x| if x > 1 { Err(x) } else { Ok(()) })),
534                    Err(2));
535
536         // test that it does not take more elements than it needs
537         let functions = [|| Ok(()), || Err(1), || fail!()];
538
539         assert_eq!(fold_(functions.iter()
540                         .map(|f| (*f)())),
541                    Err(1));
542     }
543
544     #[test]
545     pub fn test_to_option() {
546         let ok: Result<int, int> = Ok(100);
547         let err: Result<int, int> = Err(404);
548
549         assert_eq!(ok.to_option(), Some(100));
550         assert_eq!(err.to_option(), None);
551     }
552
553     #[test]
554     pub fn test_into_option() {
555         let ok: Result<int, int> = Ok(100);
556         let err: Result<int, int> = Err(404);
557
558         assert_eq!(ok.into_option(), Some(100));
559         assert_eq!(err.into_option(), None);
560     }
561
562     #[test]
563     pub fn test_as_option() {
564         let ok: Result<int, int> = Ok(100);
565         let err: Result<int, int> = Err(404);
566
567         assert_eq!(ok.as_option().unwrap(), &100);
568         assert_eq!(err.as_option(), None);
569     }
570
571     #[test]
572     pub fn test_to_result() {
573         let ok: Result<int, int> = Ok(100);
574         let err: Result<int, int> = Err(404);
575
576         assert_eq!(ok.to_result(), Ok(100));
577         assert_eq!(err.to_result(), Err(404));
578     }
579
580     #[test]
581     pub fn test_into_result() {
582         let ok: Result<int, int> = Ok(100);
583         let err: Result<int, int> = Err(404);
584
585         assert_eq!(ok.into_result(), Ok(100));
586         assert_eq!(err.into_result(), Err(404));
587     }
588
589     #[test]
590     pub fn test_as_result() {
591         let ok: Result<int, int> = Ok(100);
592         let err: Result<int, int> = Err(404);
593
594         let x = 100;
595         assert_eq!(ok.as_result(), Ok(&x));
596
597         let x = 404;
598         assert_eq!(err.as_result(), Err(&x));
599     }
600
601     #[test]
602     pub fn test_to_str() {
603         let ok: Result<int, ~str> = Ok(100);
604         let err: Result<int, ~str> = Err(~"Err");
605
606         assert_eq!(ok.to_str(), ~"Ok(100)");
607         assert_eq!(err.to_str(), ~"Err(Err)");
608     }
609
610     #[test]
611     pub fn test_fmt_default() {
612         let ok: Result<int, ~str> = Ok(100);
613         let err: Result<int, ~str> = Err(~"Err");
614
615         assert_eq!(format!("{}", ok), ~"Ok(100)");
616         assert_eq!(format!("{}", err), ~"Err(Err)");
617     }
618 }