]> git.lizzy.rs Git - rust.git/blob - src/libstd/result.rs
auto merge of #10977 : brson/rust/androidtest, r=brson
[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 clone::Clone;
14 use cmp::Eq;
15 use fmt;
16 use iter::Iterator;
17 use option::{None, Option, Some};
18 use str::OwnedStr;
19 use to_str::ToStr;
20 use vec::OwnedVector;
21 use vec;
22
23 /// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
24 #[deriving(Clone, DeepClone, Eq, Ord, TotalEq, TotalOrd, ToStr)]
25 pub enum Result<T, E> {
26     /// Contains the success value
27     Ok(T),
28
29     /// Contains the error value
30     Err(E)
31 }
32
33 /////////////////////////////////////////////////////////////////////////////
34 // Type implementation
35 /////////////////////////////////////////////////////////////////////////////
36
37 impl<T, E> Result<T, E> {
38     /////////////////////////////////////////////////////////////////////////
39     // Querying the contained values
40     /////////////////////////////////////////////////////////////////////////
41
42     /// Returns true if the result is `Ok`
43     #[inline]
44     pub fn is_ok(&self) -> bool {
45         match *self {
46             Ok(_) => true,
47             Err(_) => false
48         }
49     }
50
51     /// Returns true if the result is `Err`
52     #[inline]
53     pub fn is_err(&self) -> bool {
54         !self.is_ok()
55     }
56
57
58     /////////////////////////////////////////////////////////////////////////
59     // Adapter for each variant
60     /////////////////////////////////////////////////////////////////////////
61
62     /// Convert from `Result<T, E>` to `Option<T>`
63     #[inline]
64     pub fn ok(self) -> Option<T> {
65         match self {
66             Ok(x)  => Some(x),
67             Err(_) => None,
68         }
69     }
70
71     /// Convert from `Result<T, E>` to `Option<E>`
72     #[inline]
73     pub fn err(self) -> Option<E> {
74         match self {
75             Ok(_)  => None,
76             Err(x) => Some(x),
77         }
78     }
79
80     /////////////////////////////////////////////////////////////////////////
81     // Adapter for working with references
82     /////////////////////////////////////////////////////////////////////////
83
84     /// Convert from `Result<T, E>` to `Result<&T, &E>`
85     #[inline]
86     pub fn as_ref<'r>(&'r self) -> Result<&'r T, &'r E> {
87         match *self {
88             Ok(ref x) => Ok(x),
89             Err(ref x) => Err(x),
90         }
91     }
92
93     /// Convert from `Result<T, E>` to `Result<&mut T, &mut E>`
94     #[inline]
95     pub fn as_mut<'r>(&'r mut self) -> Result<&'r mut T, &'r mut E> {
96         match *self {
97             Ok(ref mut x) => Ok(x),
98             Err(ref mut x) => Err(x),
99         }
100     }
101
102     /////////////////////////////////////////////////////////////////////////
103     // Transforming contained values
104     /////////////////////////////////////////////////////////////////////////
105
106     /// Maps an `Result<T, E>` to `Result<U, E>` by applying a function to an
107     /// contained `Ok` value, leaving an `Err` value untouched.
108     ///
109     /// This function can be used to compose the results of two functions.
110     ///
111     /// Example:
112     ///
113     ///     let res = read_file(file).map(|buf| {
114     ///         parse_bytes(buf)
115     ///     })
116     #[inline]
117     pub fn map<U>(self, op: |T| -> U) -> Result<U,E> {
118         match self {
119           Ok(t) => Ok(op(t)),
120           Err(e) => Err(e)
121         }
122     }
123
124     /// Maps an `Result<T, E>` to `Result<T, F>` by applying a function to an
125     /// contained `Err` value, leaving an `Ok` value untouched.
126     ///
127     /// This function can be used to pass through a successful result while handling
128     /// an error.
129     #[inline]
130     pub fn map_err<F>(self, op: |E| -> F) -> Result<T,F> {
131         match self {
132           Ok(t) => Ok(t),
133           Err(e) => Err(op(e))
134         }
135     }
136
137     ////////////////////////////////////////////////////////////////////////
138     // Boolean operations on the values, eager and lazy
139     /////////////////////////////////////////////////////////////////////////
140
141     /// Returns `res` if the result is `Ok`, otherwise returns the `Err` value of `self`.
142     #[inline]
143     pub fn and<U>(self, res: Result<U, E>) -> Result<U, E> {
144         match self {
145             Ok(_) => res,
146             Err(e) => Err(e),
147         }
148     }
149
150     /// Calls `op` if the result is `Ok`, otherwise returns the `Err` value of `self`.
151     ///
152     /// This function can be used for control flow based on result values
153     #[inline]
154     pub fn and_then<U>(self, op: |T| -> Result<U, E>) -> Result<U, E> {
155         match self {
156             Ok(t) => op(t),
157             Err(e) => Err(e),
158         }
159     }
160
161     /// Returns `res` if the result is `Err`, otherwise returns the `Ok` value of `self`.
162     #[inline]
163     pub fn or(self, res: Result<T, E>) -> Result<T, E> {
164         match self {
165             Ok(_) => self,
166             Err(_) => res,
167         }
168     }
169
170     /// Calls `op` if the result is `Err`, otherwise returns the `Ok` value of `self`.
171     ///
172     /// This function can be used for control flow based on result values
173     #[inline]
174     pub fn or_else<F>(self, op: |E| -> Result<T, F>) -> Result<T, F> {
175         match self {
176             Ok(t) => Ok(t),
177             Err(e) => op(e),
178         }
179     }
180
181     /////////////////////////////////////////////////////////////////////////
182     // Common special cases
183     /////////////////////////////////////////////////////////////////////////
184
185     /// Unwraps a result, yielding the content of an `Ok`.
186     /// Fails if the value is an `Err`.
187     #[inline]
188     pub fn unwrap(self) -> T {
189         match self {
190             Ok(t) => t,
191             Err(_) => fail!("called `Result::unwrap()` on an `Err` value")
192         }
193     }
194
195     /// Unwraps a result, yielding the content of an `Err`.
196     /// Fails if the value is an `Ok`.
197     #[inline]
198     pub fn unwrap_err(self) -> E {
199         match self {
200             Ok(_) => fail!("called `Result::unwrap_err()` on an `Ok` value"),
201             Err(e) => e
202         }
203     }
204 }
205
206 /////////////////////////////////////////////////////////////////////////////
207 // Trait implementations
208 /////////////////////////////////////////////////////////////////////////////
209
210 impl<T: fmt::Default, E: fmt::Default> fmt::Default for Result<T, E> {
211     #[inline]
212     fn fmt(s: &Result<T, E>, f: &mut fmt::Formatter) {
213         match *s {
214             Ok(ref t) => write!(f.buf, "Ok({})", *t),
215             Err(ref e) => write!(f.buf, "Err({})", *e)
216         }
217     }
218 }
219
220 /////////////////////////////////////////////////////////////////////////////
221 // Free functions
222 /////////////////////////////////////////////////////////////////////////////
223
224 /// Takes each element in the iterator: if it is an error, no further
225 /// elements are taken, and the error is returned.
226 /// Should no error occur, a vector containing the values of each Result
227 /// is returned.
228 ///
229 /// Here is an example which increments every integer in a vector,
230 /// checking for overflow:
231 ///
232 ///     fn inc_conditionally(x: uint) -> Result<uint, &'static str> {
233 ///         if x == uint::max_value { return Err("overflow"); }
234 ///         else { return Ok(x+1u); }
235 ///     }
236 ///     let v = [1u, 2, 3];
237 ///     let res = collect(v.iter().map(|&x| inc_conditionally(x)));
238 ///     assert!(res == Ok(~[2u, 3, 4]));
239 #[inline]
240 pub fn collect<T, E, Iter: Iterator<Result<T, E>>>(mut iterator: Iter)
241     -> Result<~[T], E> {
242     let (lower, _) = iterator.size_hint();
243     let mut vs: ~[T] = vec::with_capacity(lower);
244     for t in iterator {
245         match t {
246             Ok(v) => vs.push(v),
247             Err(u) => return Err(u)
248         }
249     }
250     Ok(vs)
251 }
252
253 /// Perform a fold operation over the result values from an iterator.
254 ///
255 /// If an `Err` is encountered, it is immediately returned.
256 /// Otherwise, the folded value is returned.
257 #[inline]
258 pub fn fold<T,
259             V,
260             E,
261             Iter: Iterator<Result<T, E>>>(
262             mut iterator: Iter,
263             mut init: V,
264             f: |V, T| -> V)
265             -> Result<V, E> {
266     for t in iterator {
267         match t {
268             Ok(v) => init = f(init, v),
269             Err(u) => return Err(u)
270         }
271     }
272     Ok(init)
273 }
274
275 /// Perform a trivial fold operation over the result values
276 /// from an iterator.
277 ///
278 /// If an `Err` is encountered, it is immediately returned.
279 /// Otherwise, a simple `Ok(())` is returned.
280 #[inline]
281 pub fn fold_<T,E,Iter:Iterator<Result<T,E>>>(iterator: Iter) -> Result<(),E> {
282     fold(iterator, (), |_, _| ())
283 }
284
285 /////////////////////////////////////////////////////////////////////////////
286 // Tests
287 /////////////////////////////////////////////////////////////////////////////
288
289 #[cfg(test)]
290 mod tests {
291     use super::*;
292
293     use iter::range;
294     use vec::ImmutableVector;
295     use to_str::ToStr;
296
297     pub fn op1() -> Result<int, ~str> { Ok(666) }
298     pub fn op2() -> Result<int, ~str> { Err(~"sadface") }
299
300     #[test]
301     pub fn test_and() {
302         assert_eq!(op1().and(Ok(667)).unwrap(), 667);
303         assert_eq!(op1().and(Err::<(), ~str>(~"bad")).unwrap_err(), ~"bad");
304
305         assert_eq!(op2().and(Ok(667)).unwrap_err(), ~"sadface");
306         assert_eq!(op2().and(Err::<(), ~str>(~"bad")).unwrap_err(), ~"sadface");
307     }
308
309     #[test]
310     pub fn test_and_then() {
311         assert_eq!(op1().and_then(|i| Ok::<int, ~str>(i + 1)).unwrap(), 667);
312         assert_eq!(op1().and_then(|_| Err::<int, ~str>(~"bad")).unwrap_err(), ~"bad");
313
314         assert_eq!(op2().and_then(|i| Ok::<int, ~str>(i + 1)).unwrap_err(), ~"sadface");
315         assert_eq!(op2().and_then(|_| Err::<int, ~str>(~"bad")).unwrap_err(), ~"sadface");
316     }
317
318     #[test]
319     pub fn test_or() {
320         assert_eq!(op1().or(Ok(667)).unwrap(), 666);
321         assert_eq!(op1().or(Err(~"bad")).unwrap(), 666);
322
323         assert_eq!(op2().or(Ok(667)).unwrap(), 667);
324         assert_eq!(op2().or(Err(~"bad")).unwrap_err(), ~"bad");
325     }
326
327     #[test]
328     pub fn test_or_else() {
329         assert_eq!(op1().or_else(|_| Ok::<int, ~str>(667)).unwrap(), 666);
330         assert_eq!(op1().or_else(|e| Err::<int, ~str>(e + "!")).unwrap(), 666);
331
332         assert_eq!(op2().or_else(|_| Ok::<int, ~str>(667)).unwrap(), 667);
333         assert_eq!(op2().or_else(|e| Err::<int, ~str>(e + "!")).unwrap_err(), ~"sadface!");
334     }
335
336     #[test]
337     pub fn test_impl_map() {
338         assert_eq!(Ok::<~str, ~str>(~"a").map(|x| x + "b"), Ok(~"ab"));
339         assert_eq!(Err::<~str, ~str>(~"a").map(|x| x + "b"), Err(~"a"));
340     }
341
342     #[test]
343     pub fn test_impl_map_err() {
344         assert_eq!(Ok::<~str, ~str>(~"a").map_err(|x| x + "b"), Ok(~"a"));
345         assert_eq!(Err::<~str, ~str>(~"a").map_err(|x| x + "b"), Err(~"ab"));
346     }
347
348     #[test]
349     fn test_collect() {
350         assert_eq!(collect(range(0, 0)
351                            .map(|_| Ok::<int, ()>(0))),
352                    Ok(~[]));
353         assert_eq!(collect(range(0, 3)
354                            .map(|x| Ok::<int, ()>(x))),
355                    Ok(~[0, 1, 2]));
356         assert_eq!(collect(range(0, 3)
357                            .map(|x| if x > 1 { Err(x) } else { Ok(x) })),
358                    Err(2));
359
360         // test that it does not take more elements than it needs
361         let functions = [|| Ok(()), || Err(1), || fail!()];
362
363         assert_eq!(collect(functions.iter().map(|f| (*f)())),
364                    Err(1));
365     }
366
367     #[test]
368     fn test_fold() {
369         assert_eq!(fold_(range(0, 0)
370                         .map(|_| Ok::<(), ()>(()))),
371                    Ok(()));
372         assert_eq!(fold(range(0, 3)
373                         .map(|x| Ok::<int, ()>(x)),
374                         0, |a, b| a + b),
375                    Ok(3));
376         assert_eq!(fold_(range(0, 3)
377                         .map(|x| if x > 1 { Err(x) } else { Ok(()) })),
378                    Err(2));
379
380         // test that it does not take more elements than it needs
381         let functions = [|| Ok(()), || Err(1), || fail!()];
382
383         assert_eq!(fold_(functions.iter()
384                         .map(|f| (*f)())),
385                    Err(1));
386     }
387
388     #[test]
389     pub fn test_to_str() {
390         let ok: Result<int, ~str> = Ok(100);
391         let err: Result<int, ~str> = Err(~"Err");
392
393         assert_eq!(ok.to_str(), ~"Ok(100)");
394         assert_eq!(err.to_str(), ~"Err(Err)");
395     }
396
397     #[test]
398     pub fn test_fmt_default() {
399         let ok: Result<int, ~str> = Ok(100);
400         let err: Result<int, ~str> = Err(~"Err");
401
402         assert_eq!(format!("{}", ok), ~"Ok(100)");
403         assert_eq!(format!("{}", err), ~"Err(Err)");
404     }
405 }