mirror of https://github.com/rwf2/Rocket.git
Remove second lifetime from 'FromRequest'.
While offering some utility, the lifetime did not carry its weight, and in practice offered no further ability to borrow. This greatly simplifies request guard implementations.
This commit is contained in:
parent
2366bff05f
commit
70b42e6f0e
|
@ -47,10 +47,10 @@ fn parse_invocation(attr: TokenStream, input: TokenStream) -> Result<DatabaseInv
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(DatabaseInvocation {
|
Ok(DatabaseInvocation {
|
||||||
|
structure,
|
||||||
type_name: input.ident,
|
type_name: input.ident,
|
||||||
visibility: input.vis,
|
visibility: input.vis,
|
||||||
db_name: string_lit.value(),
|
db_name: string_lit.value(),
|
||||||
structure: structure,
|
|
||||||
connection_type: inner_type,
|
connection_type: inner_type,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -109,10 +109,10 @@ pub fn database_attr(attr: TokenStream, input: TokenStream) -> Result<TokenStrea
|
||||||
}
|
}
|
||||||
|
|
||||||
#[::rocket::async_trait]
|
#[::rocket::async_trait]
|
||||||
impl<'a, 'r> #request::FromRequest<'a, 'r> for #guard_type {
|
impl<'r> #request::FromRequest<'r> for #guard_type {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
async fn from_request(__r: &'a #request::Request<'r>) -> #request::Outcome<Self, ()> {
|
async fn from_request(__r: &'r #request::Request<'_>) -> #request::Outcome<Self, ()> {
|
||||||
<#conn>::from_request(__r).await.map(Self)
|
<#conn>::from_request(__r).await.map(Self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
error[E0277]: the trait bound `Unknown: Poolable` is not satisfied
|
error[E0277]: the trait bound `Unknown: Poolable` is not satisfied
|
||||||
--> $DIR/database-types.rs:7:10
|
--> $DIR/database-types.rs:7:10
|
||||||
|
|
|
|
||||||
7 | struct A(Unknown);
|
7 | struct A(Unknown);
|
||||||
| ^^^^^^^ the trait `Poolable` is not implemented for `Unknown`
|
| ^^^^^^^ the trait `Poolable` is not implemented for `Unknown`
|
||||||
|
|
|
|
||||||
::: $WORKSPACE/contrib/lib/src/databases.rs
|
::: $WORKSPACE/contrib/lib/src/databases/connection.rs
|
||||||
|
|
|
|
||||||
| pub struct Connection<K, C: Poolable> {
|
| pub struct Connection<K, C: Poolable> {
|
||||||
| -------- required by this bound in `rocket_contrib::databases::Connection`
|
| -------- required by this bound in `rocket_contrib::databases::Connection`
|
||||||
|
|
||||||
error[E0277]: the trait bound `Vec<i32>: Poolable` is not satisfied
|
error[E0277]: the trait bound `Vec<i32>: Poolable` is not satisfied
|
||||||
--> $DIR/database-types.rs:10:10
|
--> $DIR/database-types.rs:10:10
|
||||||
|
|
|
|
||||||
10 | struct B(Vec<i32>);
|
10 | struct B(Vec<i32>);
|
||||||
| ^^^^^^^^ the trait `Poolable` is not implemented for `Vec<i32>`
|
| ^^^^^^^^ the trait `Poolable` is not implemented for `Vec<i32>`
|
||||||
|
|
|
|
||||||
::: $WORKSPACE/contrib/lib/src/databases.rs
|
::: $WORKSPACE/contrib/lib/src/databases/connection.rs
|
||||||
|
|
|
|
||||||
| pub struct Connection<K, C: Poolable> {
|
| pub struct Connection<K, C: Poolable> {
|
||||||
| -------- required by this bound in `rocket_contrib::databases::Connection`
|
| -------- required by this bound in `rocket_contrib::databases::Connection`
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
error[E0277]: the trait bound `Unknown: Poolable` is not satisfied
|
error[E0277]: the trait bound `Unknown: Poolable` is not satisfied
|
||||||
--> $DIR/database-types.rs:7:10
|
--> $DIR/database-types.rs:7:10
|
||||||
|
|
|
|
||||||
7 | struct A(Unknown);
|
7 | struct A(Unknown);
|
||||||
| ^^^^^^^ the trait `Poolable` is not implemented for `Unknown`
|
| ^^^^^^^ the trait `Poolable` is not implemented for `Unknown`
|
||||||
|
|
|
|
||||||
::: $WORKSPACE/contrib/lib/src/databases.rs
|
::: $WORKSPACE/contrib/lib/src/databases/connection.rs
|
||||||
|
|
|
|
||||||
| pub struct Connection<K, C: Poolable> {
|
| pub struct Connection<K, C: Poolable> {
|
||||||
| -------- required by this bound in `rocket_contrib::databases::Connection`
|
| -------- required by this bound in `rocket_contrib::databases::Connection`
|
||||||
|
|
||||||
error[E0277]: the trait bound `Vec<i32>: Poolable` is not satisfied
|
error[E0277]: the trait bound `Vec<i32>: Poolable` is not satisfied
|
||||||
--> $DIR/database-types.rs:10:10
|
--> $DIR/database-types.rs:10:10
|
||||||
|
|
|
|
||||||
10 | struct B(Vec<i32>);
|
10 | struct B(Vec<i32>);
|
||||||
| ^^^ the trait `Poolable` is not implemented for `Vec<i32>`
|
| ^^^ the trait `Poolable` is not implemented for `Vec<i32>`
|
||||||
|
|
|
|
||||||
::: $WORKSPACE/contrib/lib/src/databases.rs
|
::: $WORKSPACE/contrib/lib/src/databases/connection.rs
|
||||||
|
|
|
|
||||||
| pub struct Connection<K, C: Poolable> {
|
| pub struct Connection<K, C: Poolable> {
|
||||||
| -------- required by this bound in `rocket_contrib::databases::Connection`
|
| -------- required by this bound in `rocket_contrib::databases::Connection`
|
||||||
|
|
|
@ -172,11 +172,11 @@ impl<K, C: Poolable> Drop for ConnectionPool<K, C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rocket::async_trait]
|
#[rocket::async_trait]
|
||||||
impl<'a, 'r, K: 'static, C: Poolable> FromRequest<'a, 'r> for Connection<K, C> {
|
impl<'r, K: 'static, C: Poolable> FromRequest<'r> for Connection<K, C> {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
async fn from_request(request: &'a Request<'r>) -> Outcome<Self, ()> {
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, ()> {
|
||||||
match request.managed_state::<ConnectionPool<K, C>>() {
|
match request.managed_state::<ConnectionPool<K, C>>() {
|
||||||
Some(c) => c.get().await.into_outcome(Status::ServiceUnavailable),
|
Some(c) => c.get().await.into_outcome(Status::ServiceUnavailable),
|
||||||
None => {
|
None => {
|
||||||
|
|
|
@ -85,10 +85,10 @@ impl Metadata<'_> {
|
||||||
/// an error is printed and an empty `Err` with status `InternalServerError`
|
/// an error is printed and an empty `Err` with status `InternalServerError`
|
||||||
/// (`500`) is returned.
|
/// (`500`) is returned.
|
||||||
#[rocket::async_trait]
|
#[rocket::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for Metadata<'a> {
|
impl<'r> FromRequest<'r> for Metadata<'r> {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, ()> {
|
async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, ()> {
|
||||||
request.guard::<State<'_, ContextManager>>().await
|
request.guard::<State<'_, ContextManager>>().await
|
||||||
.succeeded()
|
.succeeded()
|
||||||
.and_then(|cm| Some(request::Outcome::Success(Metadata(cm.inner()))))
|
.and_then(|cm| Some(request::Outcome::Success(Metadata(cm.inner()))))
|
||||||
|
|
|
@ -41,16 +41,16 @@ error[E0277]: the trait bound `Q: FromData<'_>` is not satisfied
|
||||||
| async fn from_data(req: &'r Request<'_>, data: Data) -> Outcome<Self, Self::Error>;
|
| async fn from_data(req: &'r Request<'_>, data: Data) -> Outcome<Self, Self::Error>;
|
||||||
| -- required by this bound in `rocket::data::FromData::from_data`
|
| -- required by this bound in `rocket::data::FromData::from_data`
|
||||||
|
|
||||||
error[E0277]: the trait bound `Q: FromRequest<'_, '_>` is not satisfied
|
error[E0277]: the trait bound `Q: FromRequest<'_>` is not satisfied
|
||||||
--> $DIR/route-type-errors.rs:21:10
|
--> $DIR/route-type-errors.rs:21:10
|
||||||
|
|
|
|
||||||
21 | fn f5(a: Q, foo: Q) {}
|
21 | fn f5(a: Q, foo: Q) {}
|
||||||
| ^ the trait `FromRequest<'_, '_>` is not implemented for `Q`
|
| ^ the trait `FromRequest<'_>` is not implemented for `Q`
|
||||||
|
|
|
|
||||||
::: $WORKSPACE/core/lib/src/request/from_request.rs
|
::: $WORKSPACE/core/lib/src/request/from_request.rs
|
||||||
|
|
|
|
||||||
| pub trait FromRequest<'a, 'r>: Sized {
|
| async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error>;
|
||||||
| -- required by this bound in `from_request`
|
| -- required by this bound in `from_request`
|
||||||
|
|
||||||
error[E0277]: the trait bound `Q: FromParam<'_>` is not satisfied
|
error[E0277]: the trait bound `Q: FromParam<'_>` is not satisfied
|
||||||
--> $DIR/route-type-errors.rs:21:18
|
--> $DIR/route-type-errors.rs:21:18
|
||||||
|
@ -60,16 +60,16 @@ error[E0277]: the trait bound `Q: FromParam<'_>` is not satisfied
|
||||||
|
|
|
|
||||||
= note: required by `from_param`
|
= note: required by `from_param`
|
||||||
|
|
||||||
error[E0277]: the trait bound `Q: FromRequest<'_, '_>` is not satisfied
|
error[E0277]: the trait bound `Q: FromRequest<'_>` is not satisfied
|
||||||
--> $DIR/route-type-errors.rs:24:10
|
--> $DIR/route-type-errors.rs:24:10
|
||||||
|
|
|
|
||||||
24 | fn f6(a: Q, foo: Q, good: usize, bar: Q) {}
|
24 | fn f6(a: Q, foo: Q, good: usize, bar: Q) {}
|
||||||
| ^ the trait `FromRequest<'_, '_>` is not implemented for `Q`
|
| ^ the trait `FromRequest<'_>` is not implemented for `Q`
|
||||||
|
|
|
|
||||||
::: $WORKSPACE/core/lib/src/request/from_request.rs
|
::: $WORKSPACE/core/lib/src/request/from_request.rs
|
||||||
|
|
|
|
||||||
| pub trait FromRequest<'a, 'r>: Sized {
|
| async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error>;
|
||||||
| -- required by this bound in `from_request`
|
| -- required by this bound in `from_request`
|
||||||
|
|
||||||
error[E0277]: the trait bound `Q: FromParam<'_>` is not satisfied
|
error[E0277]: the trait bound `Q: FromParam<'_>` is not satisfied
|
||||||
--> $DIR/route-type-errors.rs:24:18
|
--> $DIR/route-type-errors.rs:24:18
|
||||||
|
|
|
@ -41,16 +41,16 @@ error[E0277]: the trait bound `Q: FromData<'_>` is not satisfied
|
||||||
| async fn from_data(req: &'r Request<'_>, data: Data) -> Outcome<Self, Self::Error>;
|
| async fn from_data(req: &'r Request<'_>, data: Data) -> Outcome<Self, Self::Error>;
|
||||||
| -- required by this bound in `rocket::data::FromData::from_data`
|
| -- required by this bound in `rocket::data::FromData::from_data`
|
||||||
|
|
||||||
error[E0277]: the trait bound `Q: FromRequest<'_, '_>` is not satisfied
|
error[E0277]: the trait bound `Q: FromRequest<'_>` is not satisfied
|
||||||
--> $DIR/route-type-errors.rs:21:10
|
--> $DIR/route-type-errors.rs:21:10
|
||||||
|
|
|
|
||||||
21 | fn f5(a: Q, foo: Q) {}
|
21 | fn f5(a: Q, foo: Q) {}
|
||||||
| ^ the trait `FromRequest<'_, '_>` is not implemented for `Q`
|
| ^ the trait `FromRequest<'_>` is not implemented for `Q`
|
||||||
|
|
|
|
||||||
::: $WORKSPACE/core/lib/src/request/from_request.rs
|
::: $WORKSPACE/core/lib/src/request/from_request.rs
|
||||||
|
|
|
|
||||||
| pub trait FromRequest<'a, 'r>: Sized {
|
| async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error>;
|
||||||
| -- required by this bound in `from_request`
|
| -- required by this bound in `from_request`
|
||||||
|
|
||||||
error[E0277]: the trait bound `Q: FromParam<'_>` is not satisfied
|
error[E0277]: the trait bound `Q: FromParam<'_>` is not satisfied
|
||||||
--> $DIR/route-type-errors.rs:21:18
|
--> $DIR/route-type-errors.rs:21:18
|
||||||
|
@ -60,16 +60,16 @@ error[E0277]: the trait bound `Q: FromParam<'_>` is not satisfied
|
||||||
|
|
|
|
||||||
= note: required by `from_param`
|
= note: required by `from_param`
|
||||||
|
|
||||||
error[E0277]: the trait bound `Q: FromRequest<'_, '_>` is not satisfied
|
error[E0277]: the trait bound `Q: FromRequest<'_>` is not satisfied
|
||||||
--> $DIR/route-type-errors.rs:24:10
|
--> $DIR/route-type-errors.rs:24:10
|
||||||
|
|
|
|
||||||
24 | fn f6(a: Q, foo: Q, good: usize, bar: Q) {}
|
24 | fn f6(a: Q, foo: Q, good: usize, bar: Q) {}
|
||||||
| ^ the trait `FromRequest<'_, '_>` is not implemented for `Q`
|
| ^ the trait `FromRequest<'_>` is not implemented for `Q`
|
||||||
|
|
|
|
||||||
::: $WORKSPACE/core/lib/src/request/from_request.rs
|
::: $WORKSPACE/core/lib/src/request/from_request.rs
|
||||||
|
|
|
|
||||||
| pub trait FromRequest<'a, 'r>: Sized {
|
| async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error>;
|
||||||
| -- required by this bound in `from_request`
|
| -- required by this bound in `from_request`
|
||||||
|
|
||||||
error[E0277]: the trait bound `Q: FromParam<'_>` is not satisfied
|
error[E0277]: the trait bound `Q: FromParam<'_>` is not satisfied
|
||||||
--> $DIR/route-type-errors.rs:24:18
|
--> $DIR/route-type-errors.rs:24:18
|
||||||
|
|
|
@ -380,10 +380,10 @@ impl Provider for Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::async_trait]
|
#[crate::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for &'r Config {
|
impl<'r> FromRequest<'r> for &'r Config {
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
async fn from_request(req: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
|
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
|
||||||
request::Outcome::Success(req.config())
|
request::Outcome::Success(req.config())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,10 +182,10 @@ impl PartialEq for SecretKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::async_trait]
|
#[crate::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for &'a SecretKey {
|
impl<'r> FromRequest<'r> for &'r SecretKey {
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
async fn from_request(req: &'a Request<'r>) -> Outcome<Self, Self::Error> {
|
async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
Outcome::Success(&req.state.config.secret_key)
|
Outcome::Success(&req.state.config.secret_key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,10 +111,10 @@ pub use self::cookie::{Cookie, SameSite, Iter};
|
||||||
/// struct User(usize);
|
/// struct User(usize);
|
||||||
///
|
///
|
||||||
/// #[rocket::async_trait]
|
/// #[rocket::async_trait]
|
||||||
/// impl<'a, 'r> FromRequest<'a, 'r> for User {
|
/// impl<'r> FromRequest<'r> for User {
|
||||||
/// type Error = std::convert::Infallible;
|
/// type Error = std::convert::Infallible;
|
||||||
///
|
///
|
||||||
/// async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
|
/// async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
|
||||||
/// request.cookies()
|
/// request.cookies()
|
||||||
/// .get_private("user_id")
|
/// .get_private("user_id")
|
||||||
/// .and_then(|c| c.value().parse().ok())
|
/// .and_then(|c| c.value().parse().ok())
|
||||||
|
|
|
@ -300,10 +300,10 @@ impl fmt::Display for Limits {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::async_trait]
|
#[crate::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for &'r Limits {
|
impl<'r> FromRequest<'r> for &'r Limits {
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
async fn from_request(req: &'a Request<'r>) -> Outcome<Self, Self::Error> {
|
async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
Outcome::Success(req.limits())
|
Outcome::Success(req.limits())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -353,10 +353,10 @@ pub use self::info_kind::{Info, Kind};
|
||||||
///
|
///
|
||||||
/// // Allows a route to access the time a request was initiated.
|
/// // Allows a route to access the time a request was initiated.
|
||||||
/// #[rocket::async_trait]
|
/// #[rocket::async_trait]
|
||||||
/// impl<'a, 'r> FromRequest<'a, 'r> for StartTime {
|
/// impl<'r> FromRequest<'r> for StartTime {
|
||||||
/// type Error = ();
|
/// type Error = ();
|
||||||
///
|
///
|
||||||
/// async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, ()> {
|
/// async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, ()> {
|
||||||
/// match *request.local_cache(|| TimerStart(None)) {
|
/// match *request.local_cache(|| TimerStart(None)) {
|
||||||
/// TimerStart(Some(time)) => request::Outcome::Success(StartTime(time)),
|
/// TimerStart(Some(time)) => request::Outcome::Success(StartTime(time)),
|
||||||
/// TimerStart(None) => request::Outcome::Failure((Status::InternalServerError, ())),
|
/// TimerStart(None) => request::Outcome::Failure((Status::InternalServerError, ())),
|
||||||
|
|
|
@ -645,10 +645,10 @@ impl<'a, S: Send + 'a, E: Send + 'a, F: Send + 'a> Outcome<S, E, F> {
|
||||||
/// struct Guard2;
|
/// struct Guard2;
|
||||||
///
|
///
|
||||||
/// #[rocket::async_trait]
|
/// #[rocket::async_trait]
|
||||||
/// impl<'a, 'r> FromRequest<'a, 'r> for Guard1 {
|
/// impl<'r> FromRequest<'r> for Guard1 {
|
||||||
/// type Error = ();
|
/// type Error = ();
|
||||||
///
|
///
|
||||||
/// async fn from_request(req: &'a Request<'r>) -> request::Outcome<Self, ()> {
|
/// async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
|
||||||
/// // Attempt to fetch the guard, passing through any error or forward.
|
/// // Attempt to fetch the guard, passing through any error or forward.
|
||||||
/// let atomics = try_outcome!(req.guard::<State<'_, Atomics>>().await);
|
/// let atomics = try_outcome!(req.guard::<State<'_, Atomics>>().await);
|
||||||
/// atomics.uncached.fetch_add(1, Ordering::Relaxed);
|
/// atomics.uncached.fetch_add(1, Ordering::Relaxed);
|
||||||
|
@ -659,10 +659,10 @@ impl<'a, S: Send + 'a, E: Send + 'a, F: Send + 'a> Outcome<S, E, F> {
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// #[rocket::async_trait]
|
/// #[rocket::async_trait]
|
||||||
/// impl<'a, 'r> FromRequest<'a, 'r> for Guard2 {
|
/// impl<'r> FromRequest<'r> for Guard2 {
|
||||||
/// type Error = ();
|
/// type Error = ();
|
||||||
///
|
///
|
||||||
/// async fn from_request(req: &'a Request<'r>) -> request::Outcome<Self, ()> {
|
/// async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
|
||||||
/// // Attempt to fetch the guard, passing through any error or forward.
|
/// // Attempt to fetch the guard, passing through any error or forward.
|
||||||
/// let guard1: Guard1 = try_outcome!(req.guard::<Guard1>().await);
|
/// let guard1: Guard1 = try_outcome!(req.guard::<Guard1>().await);
|
||||||
/// Success(Guard2)
|
/// Success(Guard2)
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::net::{IpAddr, SocketAddr};
|
use std::net::{IpAddr, SocketAddr};
|
||||||
|
|
||||||
use futures::future::BoxFuture;
|
|
||||||
|
|
||||||
use crate::router::Route;
|
use crate::router::Route;
|
||||||
use crate::request::Request;
|
use crate::request::Request;
|
||||||
use crate::outcome::{self, IntoOutcome};
|
use crate::outcome::{self, IntoOutcome};
|
||||||
|
@ -60,10 +58,10 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
||||||
/// # type MyError = String;
|
/// # type MyError = String;
|
||||||
///
|
///
|
||||||
/// #[rocket::async_trait]
|
/// #[rocket::async_trait]
|
||||||
/// impl<'a, 'r> FromRequest<'a, 'r> for MyType {
|
/// impl<'r> FromRequest<'r> for MyType {
|
||||||
/// type Error = MyError;
|
/// type Error = MyError;
|
||||||
///
|
///
|
||||||
/// async fn from_request(req: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
|
/// async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
|
||||||
/// /* .. */
|
/// /* .. */
|
||||||
/// # unimplemented!()
|
/// # unimplemented!()
|
||||||
/// }
|
/// }
|
||||||
|
@ -203,42 +201,36 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
||||||
/// use rocket::http::Status;
|
/// use rocket::http::Status;
|
||||||
/// use rocket::request::{self, Outcome, Request, FromRequest};
|
/// use rocket::request::{self, Outcome, Request, FromRequest};
|
||||||
///
|
///
|
||||||
/// struct ApiKey(String);
|
/// struct ApiKey<'r>(&'r str);
|
||||||
///
|
|
||||||
/// /// Returns true if `key` is a valid API key string.
|
|
||||||
/// fn is_valid(key: &str) -> bool {
|
|
||||||
/// key == "valid_api_key"
|
|
||||||
/// }
|
|
||||||
///
|
///
|
||||||
/// #[derive(Debug)]
|
/// #[derive(Debug)]
|
||||||
/// enum ApiKeyError {
|
/// enum ApiKeyError {
|
||||||
/// BadCount,
|
|
||||||
/// Missing,
|
/// Missing,
|
||||||
/// Invalid,
|
/// Invalid,
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// #[rocket::async_trait]
|
/// #[rocket::async_trait]
|
||||||
/// impl<'a, 'r> FromRequest<'a, 'r> for ApiKey {
|
/// impl<'r> FromRequest<'r> for ApiKey<'r> {
|
||||||
/// type Error = ApiKeyError;
|
/// type Error = ApiKeyError;
|
||||||
///
|
///
|
||||||
/// async fn from_request(req: &'a Request<'r>) -> Outcome<Self, Self::Error> {
|
/// async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
/// let keys: Vec<_> = req.headers().get("x-api-key").collect();
|
/// /// Returns true if `key` is a valid API key string.
|
||||||
/// match keys.len() {
|
/// fn is_valid(key: &str) -> bool {
|
||||||
/// 0 => Outcome::Failure((Status::BadRequest, ApiKeyError::Missing)),
|
/// key == "valid_api_key"
|
||||||
/// 1 if is_valid(keys[0]) => Outcome::Success(ApiKey(keys[0].to_string())),
|
/// }
|
||||||
/// 1 => Outcome::Failure((Status::BadRequest, ApiKeyError::Invalid)),
|
///
|
||||||
/// _ => Outcome::Failure((Status::BadRequest, ApiKeyError::BadCount)),
|
/// match req.headers().get_one("x-api-key") {
|
||||||
|
/// None => Outcome::Failure((Status::BadRequest, ApiKeyError::Missing)),
|
||||||
|
/// Some(key) if is_valid(key) => Outcome::Success(ApiKey(key)),
|
||||||
|
/// Some(_) => Outcome::Failure((Status::BadRequest, ApiKeyError::Invalid)),
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// #[get("/sensitive")]
|
/// #[get("/sensitive")]
|
||||||
/// fn sensitive(key: ApiKey) -> &'static str {
|
/// fn sensitive(key: ApiKey<'_>) -> &'static str {
|
||||||
/// # let _key = key;
|
|
||||||
/// "Sensitive data."
|
/// "Sensitive data."
|
||||||
/// }
|
/// }
|
||||||
///
|
|
||||||
/// # fn main() { }
|
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// # Request-Local State
|
/// # Request-Local State
|
||||||
|
@ -264,9 +256,9 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
||||||
/// # }
|
/// # }
|
||||||
/// # }
|
/// # }
|
||||||
/// # #[rocket::async_trait]
|
/// # #[rocket::async_trait]
|
||||||
/// # impl<'a, 'r> FromRequest<'a, 'r> for Database {
|
/// # impl<'r> FromRequest<'r> for Database {
|
||||||
/// # type Error = ();
|
/// # type Error = ();
|
||||||
/// # async fn from_request(request: &'a Request<'r>) -> Outcome<Database, ()> {
|
/// # async fn from_request(request: &'r Request<'_>) -> Outcome<Database, ()> {
|
||||||
/// # Outcome::Success(Database)
|
/// # Outcome::Success(Database)
|
||||||
/// # }
|
/// # }
|
||||||
/// # }
|
/// # }
|
||||||
|
@ -274,10 +266,10 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
||||||
/// # struct Admin { user: User }
|
/// # struct Admin { user: User }
|
||||||
/// #
|
/// #
|
||||||
/// #[rocket::async_trait]
|
/// #[rocket::async_trait]
|
||||||
/// impl<'a, 'r> FromRequest<'a, 'r> for User {
|
/// impl<'r> FromRequest<'r> for User {
|
||||||
/// type Error = ();
|
/// type Error = ();
|
||||||
///
|
///
|
||||||
/// async fn from_request(request: &'a Request<'r>) -> Outcome<User, ()> {
|
/// async fn from_request(request: &'r Request<'_>) -> Outcome<User, ()> {
|
||||||
/// let db = try_outcome!(request.guard::<Database>().await);
|
/// let db = try_outcome!(request.guard::<Database>().await);
|
||||||
/// request.cookies()
|
/// request.cookies()
|
||||||
/// .get_private("user_id")
|
/// .get_private("user_id")
|
||||||
|
@ -288,10 +280,10 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// #[rocket::async_trait]
|
/// #[rocket::async_trait]
|
||||||
/// impl<'a, 'r> FromRequest<'a, 'r> for Admin {
|
/// impl<'r> FromRequest<'r> for Admin {
|
||||||
/// type Error = ();
|
/// type Error = ();
|
||||||
///
|
///
|
||||||
/// async fn from_request(request: &'a Request<'r>) -> Outcome<Admin, ()> {
|
/// async fn from_request(request: &'r Request<'_>) -> Outcome<Admin, ()> {
|
||||||
/// // This will unconditionally query the database!
|
/// // This will unconditionally query the database!
|
||||||
/// let user = try_outcome!(request.guard::<User>().await);
|
/// let user = try_outcome!(request.guard::<User>().await);
|
||||||
/// if user.is_admin {
|
/// if user.is_admin {
|
||||||
|
@ -328,9 +320,9 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
||||||
/// # }
|
/// # }
|
||||||
/// # }
|
/// # }
|
||||||
/// # #[rocket::async_trait]
|
/// # #[rocket::async_trait]
|
||||||
/// # impl<'a, 'r> FromRequest<'a, 'r> for Database {
|
/// # impl<'r> FromRequest<'r> for Database {
|
||||||
/// # type Error = ();
|
/// # type Error = ();
|
||||||
/// # async fn from_request(request: &'a Request<'r>) -> Outcome<Database, ()> {
|
/// # async fn from_request(request: &'r Request<'_>) -> Outcome<Database, ()> {
|
||||||
/// # Outcome::Success(Database)
|
/// # Outcome::Success(Database)
|
||||||
/// # }
|
/// # }
|
||||||
/// # }
|
/// # }
|
||||||
|
@ -338,10 +330,10 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
||||||
/// # struct Admin<'a> { user: &'a User }
|
/// # struct Admin<'a> { user: &'a User }
|
||||||
/// #
|
/// #
|
||||||
/// #[rocket::async_trait]
|
/// #[rocket::async_trait]
|
||||||
/// impl<'a, 'r> FromRequest<'a, 'r> for &'a User {
|
/// impl<'r> FromRequest<'r> for &'r User {
|
||||||
/// type Error = std::convert::Infallible;
|
/// type Error = std::convert::Infallible;
|
||||||
///
|
///
|
||||||
/// async fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
|
/// async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
/// // This closure will execute at most once per request, regardless of
|
/// // This closure will execute at most once per request, regardless of
|
||||||
/// // the number of times the `User` guard is executed.
|
/// // the number of times the `User` guard is executed.
|
||||||
/// let user_result = request.local_cache_async(async {
|
/// let user_result = request.local_cache_async(async {
|
||||||
|
@ -357,10 +349,10 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// #[rocket::async_trait]
|
/// #[rocket::async_trait]
|
||||||
/// impl<'a, 'r> FromRequest<'a, 'r> for Admin<'a> {
|
/// impl<'r> FromRequest<'r> for Admin<'r> {
|
||||||
/// type Error = std::convert::Infallible;
|
/// type Error = std::convert::Infallible;
|
||||||
///
|
///
|
||||||
/// async fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
|
/// async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
/// let user = try_outcome!(request.guard::<&User>().await);
|
/// let user = try_outcome!(request.guard::<&User>().await);
|
||||||
/// if user.is_admin {
|
/// if user.is_admin {
|
||||||
/// Outcome::Success(Admin { user })
|
/// Outcome::Success(Admin { user })
|
||||||
|
@ -377,7 +369,7 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
||||||
///
|
///
|
||||||
/// [request-local state]: https://rocket.rs/master/guide/state/#request-local-state
|
/// [request-local state]: https://rocket.rs/master/guide/state/#request-local-state
|
||||||
#[crate::async_trait]
|
#[crate::async_trait]
|
||||||
pub trait FromRequest<'a, 'r>: Sized {
|
pub trait FromRequest<'r>: Sized {
|
||||||
/// The associated error to be returned if derivation fails.
|
/// The associated error to be returned if derivation fails.
|
||||||
type Error: Debug;
|
type Error: Debug;
|
||||||
|
|
||||||
|
@ -387,32 +379,32 @@ pub trait FromRequest<'a, 'r>: Sized {
|
||||||
/// the derivation fails in an unrecoverable fashion, `Failure` is returned.
|
/// the derivation fails in an unrecoverable fashion, `Failure` is returned.
|
||||||
/// `Forward` is returned to indicate that the request should be forwarded
|
/// `Forward` is returned to indicate that the request should be forwarded
|
||||||
/// to other matching routes, if any.
|
/// to other matching routes, if any.
|
||||||
async fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error>;
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::async_trait]
|
#[crate::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for Method {
|
impl<'r> FromRequest<'r> for Method {
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
async fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
Success(request.method())
|
Success(request.method())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::async_trait]
|
#[crate::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for &'a Origin<'a> {
|
impl<'r> FromRequest<'r> for &'r Origin<'r> {
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
async fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
Success(request.uri())
|
Success(request.uri())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::async_trait]
|
#[crate::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for &'r Route {
|
impl<'r> FromRequest<'r> for &'r Route {
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
async fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
match request.route() {
|
match request.route() {
|
||||||
Some(route) => Success(route),
|
Some(route) => Success(route),
|
||||||
None => Forward(())
|
None => Forward(())
|
||||||
|
@ -421,19 +413,19 @@ impl<'a, 'r> FromRequest<'a, 'r> for &'r Route {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::async_trait]
|
#[crate::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for &'a CookieJar<'r> {
|
impl<'r> FromRequest<'r> for &'r CookieJar<'r> {
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
async fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
Success(request.cookies())
|
Success(request.cookies())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::async_trait]
|
#[crate::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for &'a Accept {
|
impl<'r> FromRequest<'r> for &'r Accept {
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
async fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
match request.accept() {
|
match request.accept() {
|
||||||
Some(accept) => Success(accept),
|
Some(accept) => Success(accept),
|
||||||
None => Forward(())
|
None => Forward(())
|
||||||
|
@ -442,10 +434,10 @@ impl<'a, 'r> FromRequest<'a, 'r> for &'a Accept {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::async_trait]
|
#[crate::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for &'a ContentType {
|
impl<'r> FromRequest<'r> for &'r ContentType {
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
async fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
match request.content_type() {
|
match request.content_type() {
|
||||||
Some(content_type) => Success(content_type),
|
Some(content_type) => Success(content_type),
|
||||||
None => Forward(())
|
None => Forward(())
|
||||||
|
@ -454,10 +446,10 @@ impl<'a, 'r> FromRequest<'a, 'r> for &'a ContentType {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::async_trait]
|
#[crate::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for IpAddr {
|
impl<'r> FromRequest<'r> for IpAddr {
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
async fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
match request.client_ip() {
|
match request.client_ip() {
|
||||||
Some(addr) => Success(addr),
|
Some(addr) => Success(addr),
|
||||||
None => Forward(())
|
None => Forward(())
|
||||||
|
@ -466,10 +458,10 @@ impl<'a, 'r> FromRequest<'a, 'r> for IpAddr {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::async_trait]
|
#[crate::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for SocketAddr {
|
impl<'r> FromRequest<'r> for SocketAddr {
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
async fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
match request.remote() {
|
match request.remote() {
|
||||||
Some(addr) => Success(addr),
|
Some(addr) => Success(addr),
|
||||||
None => Forward(())
|
None => Forward(())
|
||||||
|
@ -477,33 +469,27 @@ impl<'a, 'r> FromRequest<'a, 'r> for SocketAddr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'r, T: FromRequest<'a, 'r> + 'a> FromRequest<'a, 'r> for Result<T, T::Error> {
|
#[crate::async_trait]
|
||||||
|
impl<'r, T: FromRequest<'r>> FromRequest<'r> for Result<T, T::Error> {
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
fn from_request<'y>(request: &'a Request<'r>) -> BoxFuture<'y, Outcome<Self, Self::Error>>
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
where 'a: 'y, 'r: 'y
|
match T::from_request(request).await {
|
||||||
{
|
|
||||||
// TODO: FutureExt::map is a workaround (see rust-lang/rust#60658)
|
|
||||||
use futures::future::FutureExt;
|
|
||||||
T::from_request(request).map(|x| match x {
|
|
||||||
Success(val) => Success(Ok(val)),
|
Success(val) => Success(Ok(val)),
|
||||||
Failure((_, e)) => Success(Err(e)),
|
Failure((_, e)) => Success(Err(e)),
|
||||||
Forward(_) => Forward(()),
|
Forward(_) => Forward(()),
|
||||||
}).boxed()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'r, T: FromRequest<'a, 'r> + 'a> FromRequest<'a, 'r> for Option<T> {
|
#[crate::async_trait]
|
||||||
|
impl<'r, T: FromRequest<'r>> FromRequest<'r> for Option<T> {
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
fn from_request<'y>(request: &'a Request<'r>) -> BoxFuture<'y, Outcome<Self, Self::Error>>
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
where 'a: 'y, 'r: 'y
|
match T::from_request(request).await {
|
||||||
{
|
|
||||||
// TODO: FutureExt::map is a workaround (see rust-lang/rust#60658)
|
|
||||||
use futures::future::FutureExt;
|
|
||||||
T::from_request(request).map(|x| match x {
|
|
||||||
Success(val) => Success(Some(val)),
|
Success(val) => Success(Some(val)),
|
||||||
Failure(_) | Forward(_) => Success(None),
|
Failure(_) | Forward(_) => Success(None),
|
||||||
}).boxed()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -531,7 +531,7 @@ impl<'r> Request<'r> {
|
||||||
/// # })
|
/// # })
|
||||||
/// ```
|
/// ```
|
||||||
pub fn guard<'z, 'a, T>(&'a self) -> BoxFuture<'z, Outcome<T, T::Error>>
|
pub fn guard<'z, 'a, T>(&'a self) -> BoxFuture<'z, Outcome<T, T::Error>>
|
||||||
where T: FromRequest<'a, 'r> + 'z, 'a: 'z, 'r: 'z
|
where T: FromRequest<'a> + 'z, 'a: 'z, 'r: 'z
|
||||||
{
|
{
|
||||||
T::from_request(self)
|
T::from_request(self)
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,10 +237,10 @@ impl<'a> FlashMessage<'a> {
|
||||||
/// The suggested use is through an `Option` and the `FlashMessage` type alias
|
/// The suggested use is through an `Option` and the `FlashMessage` type alias
|
||||||
/// in `request`: `Option<FlashMessage>`.
|
/// in `request`: `Option<FlashMessage>`.
|
||||||
#[crate::async_trait]
|
#[crate::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for FlashMessage<'a> {
|
impl<'r> FromRequest<'r> for FlashMessage<'r> {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
async fn from_request(req: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
|
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
|
||||||
trace_!("Flash: attempting to retrieve message.");
|
trace_!("Flash: attempting to retrieve message.");
|
||||||
req.cookies().get(FLASH_COOKIE_NAME).ok_or(()).and_then(|cookie| {
|
req.cookies().get(FLASH_COOKIE_NAME).ok_or(()).and_then(|cookie| {
|
||||||
trace_!("Flash: retrieving message: {:?}", cookie);
|
trace_!("Flash: retrieving message: {:?}", cookie);
|
||||||
|
|
|
@ -50,11 +50,11 @@ impl Shutdown {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::async_trait]
|
#[crate::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for Shutdown {
|
impl<'r> FromRequest<'r> for Shutdown {
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
async fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
Outcome::Success(request.state.shutdown.clone())
|
Outcome::Success(request.state.shutdown.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,24 +53,33 @@ use crate::http::Status;
|
||||||
/// # Within Request Guards
|
/// # Within Request Guards
|
||||||
///
|
///
|
||||||
/// Because `State` is itself a request guard, managed state can be retrieved
|
/// Because `State` is itself a request guard, managed state can be retrieved
|
||||||
/// from another request guard's implementation. In the following code example,
|
/// from another request guard's implementation using either
|
||||||
/// `Item` retrieves the `MyConfig` managed state in its [`FromRequest`]
|
/// [`Request::guard()`] or [`Request::managed_state()`]. In the following code
|
||||||
/// implementation using the [`Request::guard()`] method.
|
/// example, the `Item` request guard retrieves `MyConfig` from managed state:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use rocket::State;
|
/// use rocket::State;
|
||||||
/// use rocket::request::{self, Request, FromRequest};
|
/// use rocket::request::{self, Request, FromRequest};
|
||||||
|
/// use rocket::outcome::IntoOutcome;
|
||||||
///
|
///
|
||||||
/// # struct MyConfig{ user_val: String };
|
/// # struct MyConfig{ user_val: String };
|
||||||
/// struct Item(String);
|
/// struct Item<'r>(&'r str);
|
||||||
///
|
///
|
||||||
/// #[rocket::async_trait]
|
/// #[rocket::async_trait]
|
||||||
/// impl<'a, 'r> FromRequest<'a, 'r> for Item {
|
/// impl<'r> FromRequest<'r> for Item<'r> {
|
||||||
/// type Error = ();
|
/// type Error = ();
|
||||||
///
|
///
|
||||||
/// async fn from_request(request: &'a Request<'r>) -> request::Outcome<Item, ()> {
|
/// async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, ()> {
|
||||||
/// request.guard::<State<MyConfig>>().await
|
/// // Using `State` as a request guard. Use `inner()` to get an `'r`.
|
||||||
/// .map(|my_config| Item(my_config.user_val.clone()))
|
/// let outcome = request.guard::<State<MyConfig>>().await
|
||||||
|
/// .map(|my_config| Item(&my_config.inner().user_val));
|
||||||
|
///
|
||||||
|
/// // Or alternatively, using `Request::managed_state()`:
|
||||||
|
/// let outcome = request.managed_state::<MyConfig>()
|
||||||
|
/// .map(|my_config| Item(&my_config.user_val))
|
||||||
|
/// .or_forward(());
|
||||||
|
///
|
||||||
|
/// outcome
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -160,11 +169,11 @@ impl<'r, T: Send + Sync + 'static> State<'r, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::async_trait]
|
#[crate::async_trait]
|
||||||
impl<'a, 'r, T: Send + Sync + 'static> FromRequest<'a, 'r> for State<'r, T> {
|
impl<'r, T: Send + Sync + 'static> FromRequest<'r> for State<'r, T> {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
async fn from_request(req: &'a Request<'r>) -> request::Outcome<State<'r, T>, ()> {
|
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
|
||||||
match req.state.managed.try_get::<T>() {
|
match req.state.managed.try_get::<T>() {
|
||||||
Some(state) => Outcome::Success(State(state)),
|
Some(state) => Outcome::Success(State(state)),
|
||||||
None => {
|
None => {
|
||||||
|
|
|
@ -7,10 +7,10 @@ use rocket::outcome::IntoOutcome;
|
||||||
struct HasContentType;
|
struct HasContentType;
|
||||||
|
|
||||||
#[rocket::async_trait]
|
#[rocket::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for HasContentType {
|
impl<'r> FromRequest<'r> for HasContentType {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
async fn from_request(req: &'a Request<'r>) -> request::Outcome<Self, ()> {
|
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
|
||||||
req.content_type().map(|_| HasContentType).or_forward(())
|
req.content_type().map(|_| HasContentType).or_forward(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,10 @@ use rocket::outcome::Outcome::*;
|
||||||
struct HeaderCount(usize);
|
struct HeaderCount(usize);
|
||||||
|
|
||||||
#[rocket::async_trait]
|
#[rocket::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for HeaderCount {
|
impl<'r> FromRequest<'r> for HeaderCount {
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
|
||||||
Success(HeaderCount(request.headers().len()))
|
Success(HeaderCount(request.headers().len()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,10 @@ struct Guard3;
|
||||||
struct Guard4;
|
struct Guard4;
|
||||||
|
|
||||||
#[rocket::async_trait]
|
#[rocket::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for Guard1 {
|
impl<'r> FromRequest<'r> for Guard1 {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
async fn from_request(req: &'a Request<'r>) -> request::Outcome<Self, ()> {
|
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
|
||||||
let atomics = try_outcome!(req.guard::<State<'_, Atomics>>().await);
|
let atomics = try_outcome!(req.guard::<State<'_, Atomics>>().await);
|
||||||
atomics.uncached.fetch_add(1, Ordering::Relaxed);
|
atomics.uncached.fetch_add(1, Ordering::Relaxed);
|
||||||
req.local_cache(|| atomics.cached.fetch_add(1, Ordering::Relaxed));
|
req.local_cache(|| atomics.cached.fetch_add(1, Ordering::Relaxed));
|
||||||
|
@ -33,20 +33,20 @@ impl<'a, 'r> FromRequest<'a, 'r> for Guard1 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rocket::async_trait]
|
#[rocket::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for Guard2 {
|
impl<'r> FromRequest<'r> for Guard2 {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
async fn from_request(req: &'a Request<'r>) -> request::Outcome<Self, ()> {
|
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
|
||||||
try_outcome!(req.guard::<Guard1>().await);
|
try_outcome!(req.guard::<Guard1>().await);
|
||||||
Outcome::Success(Guard2)
|
Outcome::Success(Guard2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rocket::async_trait]
|
#[rocket::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for Guard3 {
|
impl<'r> FromRequest<'r> for Guard3 {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
async fn from_request(req: &'a Request<'r>) -> request::Outcome<Self, ()> {
|
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
|
||||||
let atomics = try_outcome!(req.guard::<State<'_, Atomics>>().await);
|
let atomics = try_outcome!(req.guard::<State<'_, Atomics>>().await);
|
||||||
atomics.uncached.fetch_add(1, Ordering::Relaxed);
|
atomics.uncached.fetch_add(1, Ordering::Relaxed);
|
||||||
req.local_cache_async(async {
|
req.local_cache_async(async {
|
||||||
|
@ -58,10 +58,10 @@ impl<'a, 'r> FromRequest<'a, 'r> for Guard3 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rocket::async_trait]
|
#[rocket::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for Guard4 {
|
impl<'r> FromRequest<'r> for Guard4 {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
async fn from_request(req: &'a Request<'r>) -> request::Outcome<Self, ()> {
|
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
|
||||||
try_outcome!(Guard3::from_request(req).await);
|
try_outcome!(Guard3::from_request(req).await);
|
||||||
Outcome::Success(Guard4)
|
Outcome::Success(Guard4)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,10 +22,10 @@ struct Login {
|
||||||
struct User(usize);
|
struct User(usize);
|
||||||
|
|
||||||
#[rocket::async_trait]
|
#[rocket::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for User {
|
impl<'r> FromRequest<'r> for User {
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
async fn from_request(request: &'a Request<'r>) -> request::Outcome<User, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> request::Outcome<User, Self::Error> {
|
||||||
request.cookies()
|
request.cookies()
|
||||||
.get_private("user_id")
|
.get_private("user_id")
|
||||||
.and_then(|cookie| cookie.value().parse().ok())
|
.and_then(|cookie| cookie.value().parse().ok())
|
||||||
|
|
|
@ -128,10 +128,10 @@ use rocket::request::{self, Request, FromRequest};
|
||||||
# struct HitCount { count: AtomicUsize }
|
# struct HitCount { count: AtomicUsize }
|
||||||
# type ErrorType = ();
|
# type ErrorType = ();
|
||||||
#[rocket::async_trait]
|
#[rocket::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for T {
|
impl<'r> FromRequest<'r> for T {
|
||||||
type Error = ErrorType;
|
type Error = ErrorType;
|
||||||
|
|
||||||
async fn from_request(req: &'a Request<'r>) -> request::Outcome<T, Self::Error> {
|
async fn from_request(req: &'r Request<'_>) -> request::Outcome<T, Self::Error> {
|
||||||
let hit_count_state = try_outcome!(req.guard::<State<HitCount>>().await);
|
let hit_count_state = try_outcome!(req.guard::<State<HitCount>>().await);
|
||||||
let current_count = hit_count_state.count.load(Ordering::Relaxed);
|
let current_count = hit_count_state.count.load(Ordering::Relaxed);
|
||||||
/* ... */
|
/* ... */
|
||||||
|
@ -173,10 +173,10 @@ struct RequestId(pub usize);
|
||||||
|
|
||||||
/// Returns the current request's ID, assigning one only as necessary.
|
/// Returns the current request's ID, assigning one only as necessary.
|
||||||
#[rocket::async_trait]
|
#[rocket::async_trait]
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for &'a RequestId {
|
impl<'r> FromRequest<'r> for &'r RequestId {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
|
||||||
// The closure passed to `local_cache` will be executed at most once per
|
// The closure passed to `local_cache` will be executed at most once per
|
||||||
// request: the first time the `RequestId` guard is used. If it is
|
// request: the first time the `RequestId` guard is used. If it is
|
||||||
// requested again, `local_cache` will return the same value.
|
// requested again, `local_cache` will return the same value.
|
||||||
|
|
Loading…
Reference in New Issue