outcome/
lib.rs

1//! # The outcome crate
2//! Type `Outcome` represents a success or failure: Every `Outcome` is either `Success` or `Failure`
3//! 
4//! ```
5//! use outcome::*;
6//! 
7//! fn do_something() -> Outcome {
8//!     Success
9//! }
10//! 
11//! // The return value is an outcome
12//! let result = do_something();
13//! 
14//! // Pattern Match
15//! match result {
16//!     Success => println!("Well done!"),
17//!     Failure => println!("Oh well :("),
18//! }
19//! ```
20//! 
21//! # Examples
22//! Using `and_then` on an `Outcome`:
23//! 
24//! ```
25//! use outcome::*;
26//! 
27//! // Returns `Failure`
28//! let result = Outcome::from(false);
29//! 
30//! match result.and_then(|| Success) {
31//!     Success => println!("Success! :)"),
32//!     Failure => println!("Failure :("),
33//! }
34//! ```
35//! 
36//! Using `or_none` on an `Outcome` to transform it into an `Option`:
37//! 
38//! ```
39//! use outcome::*;
40//! 
41//! let result = Success;
42//! 
43//! // Encapsulates arg within an option
44//! match result.or_none("hello!") {
45//!     Some(s) => println!("{}", s),
46//!     None => println!("Nothing here!"),
47//! }
48//! ```
49
50pub use Outcome::{Success, Failure};
51
52#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
53pub enum Outcome {
54    /// Successful
55    Success,
56    /// Not successful
57    Failure
58}
59
60impl Outcome {
61    /// Returns `true` if the outcome is a success
62    /// 
63    /// # Examples
64    /// 
65    /// ```
66    /// use outcome::*;
67    /// 
68    /// let result = Success;
69    /// 
70    /// assert!(result.is_success());
71    /// ```
72    pub fn is_success(&self) -> bool {
73        *self == Success
74    }
75
76    /// Returns `true` if the outcome is a failure
77    /// 
78    /// # Examples
79    /// 
80    /// ```
81    /// use outcome::*;
82    /// 
83    /// let result = Failure;
84    /// 
85    /// assert!(result.is_failure());
86    /// ```
87    pub fn is_failure(&self) -> bool {
88        !self.is_success()
89    }
90
91    /// Transforms the `Outcome` into an `Option<T>`, mapping `Success` to `Some(good)` and `Failure` to `None`
92    /// 
93    /// # Examples
94    /// 
95    /// ```
96    /// use outcome::*;
97    /// 
98    /// let result = Success;
99    /// 
100    /// assert_eq!(result.or_none(42), Some(42));
101    /// ```
102    pub fn or_none<T>(self, ok: T) -> Option<T> {
103        match self {
104            Success => Some(ok),
105            Failure => None,
106        }
107    }
108
109    /// Transforms the `Outcome` into a `Result<T, E>`, mapping `Success` to `Ok(good)` and `Failure` to `Err(err)`
110    /// 
111    /// # Examples
112    /// 
113    /// ```
114    /// use outcome::*;
115    /// 
116    /// let result = Success;
117    /// 
118    /// assert_eq!(result.or_err("good", "bad"), Ok("good"));
119    /// ```
120    pub fn or_err<T, E>(self, good: T, err: E) -> Result<T, E> {
121        match self {
122            Success => Ok(good),
123            Failure => Err(err),
124        }
125    }
126
127    /// Returns `good` if the outcome is `Success`, otherwise panics
128    /// 
129    /// # Examples
130    /// 
131    /// ```
132    /// use outcome::*;
133    /// 
134    /// let result = Success;
135    /// 
136    /// assert_eq!(result.or_panic(42), 42);
137    /// ```
138    pub fn or_panic<T>(self, good: T) -> T {
139        match self {
140            Success => good,
141            Failure => panic!("Called `Outcome::or_panic(...)` on a `Failure` value"),
142        }
143    }
144
145    /// Returns `Failure` if the outcome is `Failure`, otherwise returns `outb`
146    /// 
147    /// # Examples
148    /// 
149    /// ```
150    /// use outcome::*;
151    /// 
152    /// let result = Success;
153    /// 
154    /// assert_eq!(result.and(Failure), Failure);
155    /// ```
156    pub fn and(self, outb: Outcome) -> Outcome {
157        match self {
158            Success => outb,
159            Failure => Failure,
160        }
161    }
162
163    /// Returns `Success` if the outcome is `Success`, otherwise returns `outb`
164    /// 
165    /// # Examples
166    /// 
167    /// ```
168    /// use outcome::*;
169    /// 
170    /// let result = Failure;
171    /// 
172    /// assert_eq!(result.or(Success), Success);
173    /// ```
174    pub fn or(self, outb: Outcome) -> Outcome {
175        match self {
176            Success => Success,
177            Failure => outb,
178        }
179    }
180
181    /// Returns `Failure` if the outcome is `Failure`, otherwise calls `f` and returns result
182    /// 
183    /// # Examples
184    /// 
185    /// ```
186    /// use outcome::*;
187    /// 
188    /// let result = Success;
189    /// 
190    /// assert_eq!(result.and_then(|| Failure), Failure);
191    /// ```
192    pub fn and_then<F: FnOnce() -> Outcome>(self, f: F) -> Outcome {
193        match self {
194            Success => f(),
195            Failure => Failure,
196        }
197    }
198
199    /// Returns `Success` if the outcome is `Success`, otherwise calls `f` and returns result
200    /// 
201    /// # Examples
202    /// 
203    /// ```
204    /// use outcome::*;
205    /// 
206    /// let result = Failure;
207    /// 
208    /// assert_eq!(result.or_then(|| Success), Success);
209    /// ```
210    pub fn or_then<F: FnOnce() -> Outcome>(self, f: F) -> Outcome {
211        match self {
212            Success => Success,
213            Failure => f(),
214        }
215    }
216}
217
218impl From<bool> for Outcome {
219    /// Returns `Success` if `good` is true, otherwise return `Failure`
220    /// 
221    /// # Examples
222    /// 
223    /// ```
224    /// use outcome::*;
225    /// 
226    /// let result = Outcome::from(true);
227    /// 
228    /// assert_eq!(result, Success);
229    /// ```
230    fn from(good: bool) -> Self {
231        match good {
232            true => Success,
233            false => Failure,
234        }
235    }
236}