Skip to content

Instantly share code, notes, and snippets.

@cbzehner
Created March 27, 2021 23:35
Show Gist options
  • Save cbzehner/e285786aca4142f154d45e5832a77745 to your computer and use it in GitHub Desktop.
Save cbzehner/e285786aca4142f154d45e5832a77745 to your computer and use it in GitHub Desktop.
example/request_local_state with a non-unit error type on Guard 1
❯ cargo check
Checking request_local_state v0.0.0 (/Users/cbzehner/Projects/open-source/Rocket/examples/request_local_state)
error[E0053]: method `from_request` has an incompatible type for trait
--> request_local_state/src/main.rs:28:5
|
28 | async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found `()`
|
= note: expected fn pointer `fn(&'r rocket::Request<'life0>) -> Pin<Box<(dyn std::future::Future<Output = rocket::outcome::Outcome<Guard1, (Status, std::string::String), ()>> + std::marker::Send + 'async_trait)>>`
found fn pointer `fn(&'r rocket::Request<'life0>) -> Pin<Box<(dyn std::future::Future<Output = rocket::outcome::Outcome<Guard1, (Status, ()), ()>> + std::marker::Send + 'async_trait)>>`
error[E0277]: the trait bound `(Status, ()): From<(Status, std::string::String)>` is not satisfied
--> request_local_state/src/main.rs:42:9
|
42 | try_outcome!(req.guard::<Guard1>().await);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<(Status, std::string::String)>` is not implemented for `(Status, ())`
|
= help: the following implementations were found:
<(usize, usize) as From<toml::tokens::Span>>
= note: required by `from`
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0053, E0277.
For more information about an error, try `rustc --explain E0053`.
error: could not compile `request_local_state`
To learn more, run the command again with --verbose.
#[macro_use]
extern crate rocket;
use std::sync::atomic::{AtomicUsize, Ordering};
use rocket::outcome::Outcome;
use rocket::request::{self, FromRequest, Request};
use rocket::State;
#[cfg(test)]
mod tests;
#[derive(Default)]
struct Atomics {
uncached: AtomicUsize,
cached: AtomicUsize,
}
struct Guard1;
struct Guard2;
struct Guard3;
struct Guard4;
#[rocket::async_trait]
impl<'r> FromRequest<'r> for Guard1 {
type Error = String;
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
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));
Outcome::Success(Guard1)
}
}
#[rocket::async_trait]
impl<'r> FromRequest<'r> for Guard2 {
type Error = ();
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
try_outcome!(req.guard::<Guard1>().await);
Outcome::Success(Guard2)
}
}
#[rocket::async_trait]
impl<'r> FromRequest<'r> for Guard3 {
type Error = ();
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
let atomics = try_outcome!(req.guard::<State<'_, Atomics>>().await);
atomics.uncached.fetch_add(1, Ordering::Relaxed);
req.local_cache_async(async { atomics.cached.fetch_add(1, Ordering::Relaxed) })
.await;
Outcome::Success(Guard3)
}
}
#[rocket::async_trait]
impl<'r> FromRequest<'r> for Guard4 {
type Error = ();
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
try_outcome!(Guard3::from_request(req).await);
Outcome::Success(Guard4)
}
}
#[get("/sync")]
fn r_sync(_g1: Guard1, _g2: Guard2) {
// This exists only to run the request guards.
}
#[get("/async")]
async fn r_async(_g1: Guard3, _g2: Guard4) {
// This exists only to run the request guards.
}
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite()
.manage(Atomics::default())
.mount("/", routes![r_sync, r_async])
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment