pub macro try_outcome($expr:expr $(,)?) {
...
}
Expand description
Unwraps a Success
or propagates a Forward
or
Error
by returning early.
§Syntax
The macro has the following “signature”:
use rocket::outcome::Outcome;
// Returns the inner `S` if `outcome` is `Outcome::Success`. Otherwise
// returns from the caller with `Outcome<impl From<E>, impl From<F>>`.
fn try_outcome<S, E, F>(outcome: Outcome<S, E, F>) -> S
This is just like ?
(or previously, try!
), but for Outcome
. In the
case of a Forward
or Error
variant, the inner type is passed to
From
, allowing for the conversion between
specific and more general types. The resulting forward/error is
immediately returned. Because of the early return, try_outcome!
can
only be used in methods that return Outcome
.
§Example
use std::sync::atomic::{AtomicUsize, Ordering};
use rocket::State;
use rocket::request::{self, Request, FromRequest};
use rocket::outcome::{try_outcome, Outcome::*};
#[derive(Default)]
struct Atomics {
uncached: AtomicUsize,
cached: AtomicUsize,
}
struct Guard1;
struct Guard2;
#[rocket::async_trait]
impl<'r> FromRequest<'r> for Guard1 {
type Error = ();
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
// Attempt to fetch the guard, passing through any error or forward.
let atomics = try_outcome!(req.guard::<&State<Atomics>>().await);
atomics.uncached.fetch_add(1, Ordering::Relaxed);
req.local_cache(|| atomics.cached.fetch_add(1, Ordering::Relaxed));
Success(Guard1)
}
}
#[rocket::async_trait]
impl<'r> FromRequest<'r> for Guard2 {
type Error = ();
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
// Attempt to fetch the guard, passing through any error or forward.
let guard1: Guard1 = try_outcome!(req.guard::<Guard1>().await);
Success(Guard2)
}
}