pub macro try_outcome($expr:expr $(,)?) {
...
}Available on
nightly only.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>) -> SThis 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)
}
}