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}