rocket/
outcome.rs

1//! Success, error, and forward handling.
2//!
3//! The `Outcome<S, E, F>` type is similar to the standard library's `Result<S,
4//! E>` type. It is an enum with three variants, each containing a value:
5//! `Success(S)`, which represents a successful outcome, `Error(E)`, which
6//! represents an erroring outcome, and `Forward(F)`, which represents neither a
7//! success or error, but instead, indicates that processing could not be
8//! handled and should instead be _forwarded_ to whatever can handle the
9//! processing next.
10//!
11//! The `Outcome` type is the return type of many of the core Rocket traits,
12//! including [`FromRequest`](crate::request::FromRequest), [`FromData`]
13//! [`Responder`]. It is also the return type of request handlers via the
14//! [`Response`](crate::response::Response) type.
15//!
16//! [`FromData`]: crate::data::FromData
17//! [`Responder`]: crate::response::Responder
18//!
19//! # Success
20//!
21//! A successful `Outcome<S, E, F>`, `Success(S)`, is returned from functions
22//! that complete successfully. The meaning of a `Success` outcome depends on
23//! the context. For instance, the `Outcome` of the `from_data` method of the
24//! [`FromData`] trait will be matched against the type expected by
25//! the user. For example, consider the following handler:
26//!
27//! ```rust
28//! # use rocket::post;
29//! # type S = String;
30//! #[post("/", data = "<my_val>")]
31//! fn hello(my_val: S) { /* ... */  }
32//! ```
33//!
34//! The [`FromData`] implementation for the type `S` returns an `Outcome` with a
35//! `Success(S)`. If `from_data` returns a `Success`, the `Success` value will
36//! be unwrapped and the value will be used as the value of `my_val`.
37//!
38//! # Error
39//!
40//! An error `Outcome<S, E, F>`, `Error(E)`, is returned when a function
41//! fails with some error and no processing can or should continue as a result.
42//! The meaning of an error depends on the context.
43//!
44//! In Rocket, an `Error` generally means that a request is taken out of normal
45//! processing. The request is then given to the catcher corresponding to some
46//! status code. Users can catch errors by requesting a type of `Result<S, E>`
47//! or `Option<S>` in request handlers. For example, if a user's handler looks
48//! like:
49//!
50//! ```rust
51//! # use rocket::post;
52//! # type S = Option<String>;
53//! # type E = std::convert::Infallible;
54//! #[post("/", data = "<my_val>")]
55//! fn hello(my_val: Result<S, E>) { /* ... */ }
56//! ```
57//!
58//! The [`FromData`] implementation for the type `S` returns an `Outcome` with a
59//! `Success(S)` and `Error(E)`. If `from_data` returns an `Error`, the `Error`
60//! value will be unwrapped and the value will be used as the `Err` value of
61//! `my_val` while a `Success` will be unwrapped and used the `Ok` value.
62//!
63//! # Forward
64//!
65//! A forward `Outcome<S, E, F>`, `Forward(F)`, is returned when a function
66//! wants to indicate that the requested processing should be _forwarded_ to the
67//! next available processor. Again, the exact meaning depends on the context.
68//!
69//! In Rocket, a `Forward` generally means that a request is forwarded to the
70//! next available request handler. For example, consider the following request
71//! handler:
72//!
73//! ```rust
74//! # use rocket::post;
75//! # type S = String;
76//! #[post("/", data = "<my_val>")]
77//! fn hello(my_val: S) { /* ... */ }
78//! ```
79//!
80//! The [`FromData`] implementation for the type `S` returns an `Outcome` with a
81//! `Success(S)`, `Error(E)`, and `Forward(F)`. If the `Outcome` is a
82//! `Forward`, the `hello` handler isn't called. Instead, the incoming request
83//! is forwarded, or passed on to, the next matching route, if any. Ultimately,
84//! if there are no non-forwarding routes, forwarded requests are handled by the
85//! 404 catcher. Similar to `Error`s, users can catch `Forward`s by requesting
86//! a type of `Option<S>`. If an `Outcome` is a `Forward`, the `Option` will be
87//! `None`.
88
89use std::fmt;
90
91use yansi::{Paint, Color};
92
93use crate::{route, request, response};
94use crate::data::{self, Data, FromData};
95use crate::http::Status;
96
97use self::Outcome::*;
98
99/// An enum representing success (`Success`), error (`Error`), or forwarding
100/// (`Forward`).
101///
102/// See the [top level documentation](crate::outcome) for detailed information.
103#[must_use]
104#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
105pub enum Outcome<S, E, F> {
106    /// Contains the success value.
107    Success(S),
108    /// Contains the error error value.
109    Error(E),
110    /// Contains the value to forward on.
111    Forward(F),
112}
113
114impl<S, E, F> Outcome<S, E, F> {
115    /// Unwraps the Outcome, yielding the contents of a Success.
116    ///
117    /// # Panics
118    ///
119    /// Panics if the value is not `Success`.
120    ///
121    /// # Examples
122    ///
123    /// ```rust
124    /// # use rocket::outcome::Outcome;
125    /// # use rocket::outcome::Outcome::*;
126    /// #
127    /// let x: Outcome<i32, &str, usize> = Success(10);
128    /// assert_eq!(x.unwrap(), 10);
129    /// ```
130    #[inline]
131    #[track_caller]
132    pub fn unwrap(self) -> S {
133        match self {
134            Success(val) => val,
135            _ => panic!("unwrapped a non-successful outcome")
136        }
137    }
138
139    /// Unwraps the Outcome, yielding the contents of a Success.
140    ///
141    /// # Panics
142    ///
143    /// If the value is not `Success`, panics with the given `message`.
144    ///
145    /// # Examples
146    ///
147    /// ```rust
148    /// # use rocket::outcome::Outcome;
149    /// # use rocket::outcome::Outcome::*;
150    /// #
151    /// let x: Outcome<i32, &str, usize> = Success(10);
152    /// assert_eq!(x.expect("success value"), 10);
153    /// ```
154    #[inline]
155    #[track_caller]
156    pub fn expect(self, message: &str) -> S {
157        match self {
158            Success(val) => val,
159            _ => panic!("unwrapped a non-successful outcome: {}", message)
160        }
161    }
162
163    /// Return true if this `Outcome` is a `Success`.
164    ///
165    /// # Examples
166    ///
167    /// ```rust
168    /// # use rocket::outcome::Outcome;
169    /// # use rocket::outcome::Outcome::*;
170    /// #
171    /// let x: Outcome<i32, &str, usize> = Success(10);
172    /// assert_eq!(x.is_success(), true);
173    ///
174    /// let x: Outcome<i32, &str, usize> = Error("Hi! I'm an error.");
175    /// assert_eq!(x.is_success(), false);
176    ///
177    /// let x: Outcome<i32, &str, usize> = Forward(25);
178    /// assert_eq!(x.is_success(), false);
179    /// ```
180    #[inline]
181    pub fn is_success(&self) -> bool {
182        matches!(self, Success(_))
183    }
184
185    /// Return true if this `Outcome` is an `Error`.
186    ///
187    /// # Examples
188    ///
189    /// ```rust
190    /// # use rocket::outcome::Outcome;
191    /// # use rocket::outcome::Outcome::*;
192    /// #
193    /// let x: Outcome<i32, &str, usize> = Success(10);
194    /// assert_eq!(x.is_error(), false);
195    ///
196    /// let x: Outcome<i32, &str, usize> = Error("Hi! I'm an error.");
197    /// assert_eq!(x.is_error(), true);
198    ///
199    /// let x: Outcome<i32, &str, usize> = Forward(25);
200    /// assert_eq!(x.is_error(), false);
201    /// ```
202    #[inline]
203    pub fn is_error(&self) -> bool {
204        matches!(self, Error(_))
205    }
206
207    /// Return true if this `Outcome` is a `Forward`.
208    ///
209    /// # Examples
210    ///
211    /// ```rust
212    /// # use rocket::outcome::Outcome;
213    /// # use rocket::outcome::Outcome::*;
214    /// #
215    /// let x: Outcome<i32, &str, usize> = Success(10);
216    /// assert_eq!(x.is_forward(), false);
217    ///
218    /// let x: Outcome<i32, &str, usize> = Error("Hi! I'm an error.");
219    /// assert_eq!(x.is_forward(), false);
220    ///
221    /// let x: Outcome<i32, &str, usize> = Forward(25);
222    /// assert_eq!(x.is_forward(), true);
223    /// ```
224    #[inline]
225    pub fn is_forward(&self) -> bool {
226        matches!(self, Forward(_))
227    }
228
229    /// Converts from `Outcome<S, E, F>` to `Option<S>`.
230    ///
231    /// Returns the `Some` of the `Success` if this is a `Success`, otherwise
232    /// returns `None`. `self` is consumed, and all other values are discarded.
233    ///
234    /// ```rust
235    /// # use rocket::outcome::Outcome;
236    /// # use rocket::outcome::Outcome::*;
237    /// #
238    /// let x: Outcome<i32, &str, usize> = Success(10);
239    /// assert_eq!(x.succeeded(), Some(10));
240    ///
241    /// let x: Outcome<i32, &str, usize> = Error("Hi! I'm an error.");
242    /// assert_eq!(x.succeeded(), None);
243    ///
244    /// let x: Outcome<i32, &str, usize> = Forward(25);
245    /// assert_eq!(x.succeeded(), None);
246    /// ```
247    #[inline]
248    pub fn succeeded(self) -> Option<S> {
249        match self {
250            Success(val) => Some(val),
251            _ => None
252        }
253    }
254
255    /// Converts from `Outcome<S, E, F>` to `Option<E>`.
256    ///
257    /// Returns the `Some` of the `Error` if this is an `Error`, otherwise
258    /// returns `None`. `self` is consumed, and all other values are discarded.
259    ///
260    /// ```rust
261    /// # use rocket::outcome::Outcome;
262    /// # use rocket::outcome::Outcome::*;
263    /// #
264    /// let x: Outcome<i32, &str, usize> = Success(10);
265    /// assert_eq!(x.failed(), None);
266    ///
267    /// let x: Outcome<i32, &str, usize> = Error("Hi! I'm an error.");
268    /// assert_eq!(x.failed(), Some("Hi! I'm an error."));
269    ///
270    /// let x: Outcome<i32, &str, usize> = Forward(25);
271    /// assert_eq!(x.failed(), None);
272    /// ```
273    #[inline]
274    pub fn failed(self) -> Option<E> {
275        match self {
276            Error(val) => Some(val),
277            _ => None
278        }
279    }
280
281    /// Converts from `Outcome<S, E, F>` to `Option<F>`.
282    ///
283    /// Returns the `Some` of the `Forward` if this is a `Forward`, otherwise
284    /// returns `None`. `self` is consumed, and all other values are discarded.
285    ///
286    /// ```rust
287    /// # use rocket::outcome::Outcome;
288    /// # use rocket::outcome::Outcome::*;
289    /// #
290    /// let x: Outcome<i32, &str, usize> = Success(10);
291    /// assert_eq!(x.forwarded(), None);
292    ///
293    /// let x: Outcome<i32, &str, usize> = Error("Hi! I'm an error.");
294    /// assert_eq!(x.forwarded(), None);
295    ///
296    /// let x: Outcome<i32, &str, usize> = Forward(25);
297    /// assert_eq!(x.forwarded(), Some(25));
298    /// ```
299    #[inline]
300    pub fn forwarded(self) -> Option<F> {
301        match self {
302            Forward(val) => Some(val),
303            _ => None
304        }
305    }
306
307    /// Returns a `Success` value as `Ok()` or `value` in `Err`. Converts from
308    /// `Outcome<S, E, F>` to `Result<S, T>` for a given `T`.
309    ///
310    /// Returns `Ok` with the `Success` value if this is a `Success`, otherwise
311    /// returns an `Err` with the provided value. `self` is consumed, and all
312    /// other values are discarded.
313    ///
314    /// ```rust
315    /// # use rocket::outcome::Outcome;
316    /// # use rocket::outcome::Outcome::*;
317    /// #
318    /// let x: Outcome<i32, &str, usize> = Success(10);
319    /// assert_eq!(x.success_or(false), Ok(10));
320    ///
321    /// let x: Outcome<i32, &str, usize> = Error("Hi! I'm an error.");
322    /// assert_eq!(x.success_or(false), Err(false));
323    ///
324    /// let x: Outcome<i32, &str, usize> = Forward(25);
325    /// assert_eq!(x.success_or("whoops"), Err("whoops"));
326    /// ```
327    #[inline]
328    pub fn success_or<T>(self, value: T) -> Result<S, T> {
329        match self {
330            Success(val) => Ok(val),
331            _ => Err(value)
332        }
333    }
334
335    /// Returns a `Success` value as `Ok()` or `f()` in `Err`. Converts from
336    /// `Outcome<S, E, F>` to `Result<S, T>` for a given `T` produced from a
337    /// supplied function or closure.
338    ///
339    /// Returns `Ok` with the `Success` value if this is a `Success`, otherwise
340    /// returns an `Err` with the result of calling `f`. `self` is consumed, and
341    /// all other values are discarded.
342    ///
343    /// ```rust
344    /// # use rocket::outcome::Outcome;
345    /// # use rocket::outcome::Outcome::*;
346    /// #
347    /// let x: Outcome<i32, &str, usize> = Success(10);
348    /// assert_eq!(x.success_or_else(|| false), Ok(10));
349    ///
350    /// let x: Outcome<i32, &str, usize> = Error("Hi! I'm an error.");
351    /// assert_eq!(x.success_or_else(|| false), Err(false));
352    ///
353    /// let x: Outcome<i32, &str, usize> = Forward(25);
354    /// assert_eq!(x.success_or_else(|| "whoops"), Err("whoops"));
355    /// ```
356    #[inline]
357    pub fn success_or_else<T, V: FnOnce() -> T>(self, f: V) -> Result<S, T> {
358        match self {
359            Success(val) => Ok(val),
360            _ => Err(f())
361        }
362    }
363
364    /// Converts from `Outcome<S, E, F>` to `Outcome<&S, &E, &F>`.
365    ///
366    /// ```rust
367    /// # use rocket::outcome::Outcome;
368    /// # use rocket::outcome::Outcome::*;
369    /// #
370    /// let x: Outcome<i32, &str, usize> = Success(10);
371    /// assert_eq!(x.as_ref(), Success(&10));
372    ///
373    /// let x: Outcome<i32, &str, usize> = Error("Hi! I'm an error.");
374    /// assert_eq!(x.as_ref(), Error(&"Hi! I'm an error."));
375    /// ```
376    #[inline]
377    pub fn as_ref(&self) -> Outcome<&S, &E, &F> {
378        match *self {
379            Success(ref val) => Success(val),
380            Error(ref val) => Error(val),
381            Forward(ref val) => Forward(val),
382        }
383    }
384
385    /// Converts from `Outcome<S, E, F>` to `Outcome<&mut S, &mut E, &mut F>`.
386    ///
387    /// ```rust
388    /// # use rocket::outcome::Outcome;
389    /// # use rocket::outcome::Outcome::*;
390    /// #
391    /// let mut x: Outcome<i32, &str, usize> = Success(10);
392    /// if let Success(val) = x.as_mut() {
393    ///     *val = 20;
394    /// }
395    ///
396    /// assert_eq!(x.unwrap(), 20);
397    /// ```
398    #[inline]
399    pub fn as_mut(&mut self) -> Outcome<&mut S, &mut E, &mut F> {
400        match *self {
401            Success(ref mut val) => Success(val),
402            Error(ref mut val) => Error(val),
403            Forward(ref mut val) => Forward(val),
404        }
405    }
406
407    /// Maps the `Success` value using `f`. Maps an `Outcome<S, E, F>` to an
408    /// `Outcome<T, E, F>` by applying the function `f` to the value of type `S`
409    /// in `self` if `self` is an `Outcome::Success`.
410    ///
411    /// ```rust
412    /// # use rocket::outcome::Outcome;
413    /// # use rocket::outcome::Outcome::*;
414    /// #
415    /// let x: Outcome<i32, &str, usize> = Success(10);
416    ///
417    /// let mapped = x.map(|v| if v == 10 { "10" } else { "not 10" });
418    /// assert_eq!(mapped, Success("10"));
419    /// ```
420    #[inline]
421    pub fn map<T, M: FnOnce(S) -> T>(self, f: M) -> Outcome<T, E, F> {
422        match self {
423            Success(val) => Success(f(val)),
424            Error(val) => Error(val),
425            Forward(val) => Forward(val),
426        }
427    }
428
429    /// Maps the `Error` value using `f`. Maps an `Outcome<S, E, F>` to an
430    /// `Outcome<S, T, F>` by applying the function `f` to the value of type `E`
431    /// in `self` if `self` is an `Outcome::Error`.
432    ///
433    /// ```rust
434    /// # use rocket::outcome::Outcome;
435    /// # use rocket::outcome::Outcome::*;
436    /// #
437    /// let x: Outcome<i32, &str, usize> = Error("hi");
438    ///
439    /// let mapped = x.map_error(|v| if v == "hi" { 10 } else { 0 });
440    /// assert_eq!(mapped, Error(10));
441    /// ```
442    #[inline]
443    pub fn map_error<T, M: FnOnce(E) -> T>(self, f: M) -> Outcome<S, T, F> {
444        match self {
445            Success(val) => Success(val),
446            Error(val) => Error(f(val)),
447            Forward(val) => Forward(val),
448        }
449    }
450
451    /// Maps the `Forward` value using `f`. Maps an `Outcome<S, E, F>` to an
452    /// `Outcome<S, E, T>` by applying the function `f` to the value of type `F`
453    /// in `self` if `self` is an `Outcome::Forward`.
454    ///
455    /// ```rust
456    /// # use rocket::outcome::Outcome;
457    /// # use rocket::outcome::Outcome::*;
458    /// #
459    /// let x: Outcome<i32, &str, usize> = Forward(5);
460    ///
461    /// let mapped = x.map_forward(|v| if v == 5 { "a" } else { "b" });
462    /// assert_eq!(mapped, Forward("a"));
463    /// ```
464    #[inline]
465    pub fn map_forward<T, M: FnOnce(F) -> T>(self, f: M) -> Outcome<S, E, T> {
466        match self {
467            Success(val) => Success(val),
468            Error(val) => Error(val),
469            Forward(val) => Forward(f(val)),
470        }
471    }
472
473    /// Converts from `Outcome<S, E, F>` to `Outcome<T, E, F>` using `f` to map
474    /// `Success(S)` to `Success(T)`.
475    ///
476    /// If `self` is not `Success`, `self` is returned.
477    ///
478    /// # Examples
479    ///
480    /// ```rust
481    /// # use rocket::outcome::Outcome;
482    /// # use rocket::outcome::Outcome::*;
483    /// #
484    /// let x: Outcome<i32, &str, bool> = Success(10);
485    ///
486    /// let mapped = x.and_then(|v| match v {
487    ///    10 => Success("10"),
488    ///    1 => Forward(false),
489    ///    _ => Error("30")
490    /// });
491    ///
492    /// assert_eq!(mapped, Success("10"));
493    /// ```
494    #[inline]
495    pub fn and_then<T, M: FnOnce(S) -> Outcome<T, E, F>>(self, f: M) -> Outcome<T, E, F> {
496        match self {
497            Success(val) => f(val),
498            Error(val) => Error(val),
499            Forward(val) => Forward(val),
500        }
501    }
502
503    /// Converts from `Outcome<S, E, F>` to `Outcome<S, T, F>` using `f` to map
504    /// `Error(E)` to `Error(T)`.
505    ///
506    /// If `self` is not `Error`, `self` is returned.
507    ///
508    /// # Examples
509    ///
510    /// ```rust
511    /// # use rocket::outcome::Outcome;
512    /// # use rocket::outcome::Outcome::*;
513    /// #
514    /// let x: Outcome<i32, &str, bool> = Error("hi");
515    ///
516    /// let mapped = x.error_then(|v| match v {
517    ///    "hi" => Error(10),
518    ///    "test" => Forward(false),
519    ///    _ => Success(10)
520    /// });
521    ///
522    /// assert_eq!(mapped, Error(10));
523    /// ```
524    #[inline]
525    pub fn error_then<T, M: FnOnce(E) -> Outcome<S, T, F>>(self, f: M) -> Outcome<S, T, F> {
526        match self {
527            Success(val) => Success(val),
528            Error(val) => f(val),
529            Forward(val) => Forward(val),
530        }
531    }
532
533    /// Converts from `Outcome<S, E, F>` to `Outcome<S, E, T>` using `f` to map
534    /// `Forward(F)` to `Forward(T)`.
535    ///
536    /// If `self` is not `Forward`, `self` is returned.
537    ///
538    /// # Examples
539    ///
540    /// ```rust
541    /// # use rocket::outcome::Outcome;
542    /// # use rocket::outcome::Outcome::*;
543    /// #
544    /// let x: Outcome<i32, &str, Option<bool>> = Forward(Some(false));
545    ///
546    /// let mapped = x.forward_then(|v| match v {
547    ///    Some(true) => Success(10),
548    ///    Some(false) => Forward(20),
549    ///    None => Error("10")
550    /// });
551    ///
552    /// assert_eq!(mapped, Forward(20));
553    /// ```
554    #[inline]
555    pub fn forward_then<T, M: FnOnce(F) -> Outcome<S, E, T>>(self, f: M) -> Outcome<S, E, T> {
556        match self {
557            Success(val) => Success(val),
558            Error(val) => Error(val),
559            Forward(val) => f(val),
560        }
561    }
562
563    /// Converts `Outcome<S, E, F>` to `Result<S, E>` by identity mapping
564    /// `Success(S)` and `Error(E)` to `Result<T, E>` and mapping `Forward(F)`
565    /// to `Result<T, E>` using `f`.
566    ///
567    /// ```rust
568    /// # use rocket::outcome::Outcome;
569    /// # use rocket::outcome::Outcome::*;
570    /// #
571    /// let x: Outcome<i32, &str, usize> = Success(10);
572    /// assert_eq!(x.ok_map_forward(|x| Ok(x as i32 + 1)), Ok(10));
573    ///
574    /// let x: Outcome<i32, &str, usize> = Error("hello");
575    /// assert_eq!(x.ok_map_forward(|x| Ok(x as i32 + 1)), Err("hello"));
576    ///
577    /// let x: Outcome<i32, &str, usize> = Forward(0);
578    /// assert_eq!(x.ok_map_forward(|x| Ok(x as i32 + 1)), Ok(1));
579    /// ```
580    #[inline]
581    pub fn ok_map_forward<M>(self, f: M) -> Result<S, E>
582        where M: FnOnce(F) -> Result<S, E>
583    {
584        match self {
585            Outcome::Success(s) => Ok(s),
586            Outcome::Error(e) => Err(e),
587            Outcome::Forward(v) => f(v),
588        }
589    }
590
591    /// Converts `Outcome<S, E, F>` to `Result<S, E>` by identity mapping
592    /// `Success(S)` and `Forward(F)` to `Result<T, F>` and mapping `Error(E)`
593    /// to `Result<T, F>` using `f`.
594    ///
595    /// ```rust
596    /// # use rocket::outcome::Outcome;
597    /// # use rocket::outcome::Outcome::*;
598    /// #
599    /// let x: Outcome<i32, &str, usize> = Success(10);
600    /// assert_eq!(x.ok_map_error(|s| Ok(123)), Ok(10));
601    ///
602    /// let x: Outcome<i32, &str, usize> = Error("hello");
603    /// assert_eq!(x.ok_map_error(|s| Ok(123)), Ok(123));
604    ///
605    /// let x: Outcome<i32, &str, usize> = Forward(0);
606    /// assert_eq!(x.ok_map_error(|s| Ok(123)), Err(0));
607    /// ```
608    #[inline]
609    pub fn ok_map_error<M>(self, f: M) -> Result<S, F>
610        where M: FnOnce(E) -> Result<S, F>
611    {
612        match self {
613            Outcome::Success(s) => Ok(s),
614            Outcome::Error(e) => f(e),
615            Outcome::Forward(v) => Err(v),
616        }
617    }
618}
619
620impl<'a, S: Send + 'a, E: Send + 'a, F: Send + 'a> Outcome<S, E, F> {
621    /// Pins a future that resolves to `self`, returning a
622    /// [`BoxFuture`](crate::futures::future::BoxFuture) that resolves to
623    /// `self`.
624    #[inline]
625    pub fn pin(self) -> futures::future::BoxFuture<'a, Self> {
626        Box::pin(async move { self })
627    }
628}
629
630crate::export! {
631    /// Unwraps a [`Success`](Outcome::Success) or propagates a `Forward` or
632    /// `Error` by returning early.
633    ///
634    /// # Syntax
635    ///
636    /// The macro has the following "signature":
637    ///
638    /// ```rust
639    /// use rocket::outcome::Outcome;
640    ///
641    /// // Returns the inner `S` if `outcome` is `Outcome::Success`. Otherwise
642    /// // returns from the caller with `Outcome<impl From<E>, impl From<F>>`.
643    /// fn try_outcome<S, E, F>(outcome: Outcome<S, E, F>) -> S
644    /// # { unimplemented!() }
645    /// ```
646    ///
647    /// This is just like `?` (or previously, `try!`), but for `Outcome`. In the
648    /// case of a `Forward` or `Error` variant, the inner type is passed to
649    /// [`From`](std::convert::From), allowing for the conversion between
650    /// specific and more general types. The resulting forward/error is
651    /// immediately returned. Because of the early return, `try_outcome!` can
652    /// only be used in methods that return [`Outcome`].
653    ///
654    /// [`Outcome`]: crate::outcome::Outcome
655    ///
656    /// ## Example
657    ///
658    /// ```rust,no_run
659    /// # #[macro_use] extern crate rocket;
660    /// use std::sync::atomic::{AtomicUsize, Ordering};
661    ///
662    /// use rocket::State;
663    /// use rocket::request::{self, Request, FromRequest};
664    /// use rocket::outcome::{try_outcome, Outcome::*};
665    ///
666    /// #[derive(Default)]
667    /// struct Atomics {
668    ///     uncached: AtomicUsize,
669    ///     cached: AtomicUsize,
670    /// }
671    ///
672    /// struct Guard1;
673    /// struct Guard2;
674    ///
675    /// #[rocket::async_trait]
676    /// impl<'r> FromRequest<'r> for Guard1 {
677    ///     type Error = ();
678    ///
679    ///     async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
680    ///         // Attempt to fetch the guard, passing through any error or forward.
681    ///         let atomics = try_outcome!(req.guard::<&State<Atomics>>().await);
682    ///         atomics.uncached.fetch_add(1, Ordering::Relaxed);
683    ///         req.local_cache(|| atomics.cached.fetch_add(1, Ordering::Relaxed));
684    ///
685    ///         Success(Guard1)
686    ///     }
687    /// }
688    ///
689    /// #[rocket::async_trait]
690    /// impl<'r> FromRequest<'r> for Guard2 {
691    ///     type Error = ();
692    ///
693    ///     async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
694    ///         // Attempt to fetch the guard, passing through any error or forward.
695    ///         let guard1: Guard1 = try_outcome!(req.guard::<Guard1>().await);
696    ///         Success(Guard2)
697    ///     }
698    /// }
699    /// ```
700    macro_rules! try_outcome {
701        ($expr:expr $(,)?) => (match $expr {
702            $crate::outcome::Outcome::Success(val) => val,
703            $crate::outcome::Outcome::Error(e) => {
704                return $crate::outcome::Outcome::Error(::std::convert::From::from(e))
705            },
706            $crate::outcome::Outcome::Forward(f) => {
707                return $crate::outcome::Outcome::Forward(::std::convert::From::from(f))
708            },
709        });
710    }
711}
712
713impl<S, E, F> Outcome<S, E, F> {
714    #[inline]
715    fn dbg_str(&self) -> &'static str {
716        match self {
717            Success(..) => "Success",
718            Error(..) => "Error",
719            Forward(..) => "Forward",
720        }
721    }
722
723    #[inline]
724    fn color(&self) -> Color {
725        match self {
726            Success(..) => Color::Green,
727            Error(..) => Color::Red,
728            Forward(..) => Color::Yellow,
729        }
730    }
731}
732
733pub(crate) struct Display<'a, 'r>(&'a route::Outcome<'r>);
734
735impl<'r> route::Outcome<'r> {
736    pub(crate) fn log_display(&self) -> Display<'_, 'r> {
737        impl fmt::Display for Display<'_, '_> {
738            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
739                write!(f, "{}", "Outcome: ".primary().bold())?;
740
741                let color = self.0.color();
742                match self.0 {
743                    Success(r) => write!(f, "{}({})", "Success".paint(color), r.status().primary()),
744                    Error(s) => write!(f, "{}({})", "Error".paint(color), s.primary()),
745                    Forward((_, s)) => write!(f, "{}({})", "Forward".paint(color), s.primary()),
746                }
747            }
748        }
749
750        Display(self)
751    }
752}
753
754impl<S, E, F> fmt::Debug for Outcome<S, E, F> {
755    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
756        write!(f, "Outcome::{}", self.dbg_str())
757    }
758}
759
760impl<S, E, F> fmt::Display for Outcome<S, E, F> {
761    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
762        write!(f, "{}", self.dbg_str().paint(self.color()))
763    }
764}
765
766/// Conversion trait from some type into an Outcome type.
767pub trait IntoOutcome<Outcome> {
768    /// The type to use when returning an `Outcome::Error`.
769    type Error: Sized;
770
771    /// The type to use when returning an `Outcome::Forward`.
772    type Forward: Sized;
773
774    /// Converts `self` into an `Outcome`. If `self` represents a success, an
775    /// `Outcome::Success` is returned. Otherwise, an `Outcome::Error` is
776    /// returned with `error` as the inner value.
777    fn or_error(self, error: Self::Error) -> Outcome;
778
779    /// Converts `self` into an `Outcome`. If `self` represents a success, an
780    /// `Outcome::Success` is returned. Otherwise, an `Outcome::Forward` is
781    /// returned with `forward` as the inner value.
782    fn or_forward(self, forward: Self::Forward) -> Outcome;
783}
784
785impl<S, E, F> IntoOutcome<Outcome<S, E, F>> for Option<S> {
786    type Error = E;
787    type Forward = F;
788
789    #[inline]
790    fn or_error(self, error: E) -> Outcome<S, E, F> {
791        match self {
792            Some(val) => Success(val),
793            None => Error(error)
794        }
795    }
796
797    #[inline]
798    fn or_forward(self, forward: F) -> Outcome<S, E, F> {
799        match self {
800            Some(val) => Success(val),
801            None => Forward(forward)
802        }
803    }
804}
805
806impl<'r, T: FromData<'r>> IntoOutcome<data::Outcome<'r, T>> for Result<T, T::Error> {
807    type Error = Status;
808    type Forward = (Data<'r>, Status);
809
810    #[inline]
811    fn or_error(self, error: Status) -> data::Outcome<'r, T> {
812        match self {
813            Ok(val) => Success(val),
814            Err(err) => Error((error, err))
815        }
816    }
817
818    #[inline]
819    fn or_forward(self, (data, forward): (Data<'r>, Status)) -> data::Outcome<'r, T> {
820        match self {
821            Ok(val) => Success(val),
822            Err(_) => Forward((data, forward))
823        }
824    }
825}
826
827impl<S, E> IntoOutcome<request::Outcome<S, E>> for Result<S, E> {
828    type Error = Status;
829    type Forward = Status;
830
831    #[inline]
832    fn or_error(self, error: Status) -> request::Outcome<S, E> {
833        match self {
834            Ok(val) => Success(val),
835            Err(err) => Error((error, err))
836        }
837    }
838
839    #[inline]
840    fn or_forward(self, status: Status) -> request::Outcome<S, E> {
841        match self {
842            Ok(val) => Success(val),
843            Err(_) => Forward(status)
844        }
845    }
846}
847
848impl<'r, 'o: 'r> IntoOutcome<route::Outcome<'r>> for response::Result<'o> {
849    type Error = ();
850    type Forward = (Data<'r>, Status);
851
852    #[inline]
853    fn or_error(self, _: ()) -> route::Outcome<'r> {
854        match self {
855            Ok(val) => Success(val),
856            Err(status) => Error(status),
857        }
858    }
859
860    #[inline]
861    fn or_forward(self, (data, forward): (Data<'r>, Status)) -> route::Outcome<'r> {
862        match self {
863            Ok(val) => Success(val),
864            Err(_) => Forward((data, forward))
865        }
866    }
867}