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 {
|
||||
structure,
|
||||
type_name: input.ident,
|
||||
visibility: input.vis,
|
||||
db_name: string_lit.value(),
|
||||
structure: structure,
|
||||
connection_type: inner_type,
|
||||
})
|
||||
}
|
||||
|
@ -109,10 +109,10 @@ pub fn database_attr(attr: TokenStream, input: TokenStream) -> Result<TokenStrea
|
|||
}
|
||||
|
||||
#[::rocket::async_trait]
|
||||
impl<'a, 'r> #request::FromRequest<'a, 'r> for #guard_type {
|
||||
impl<'r> #request::FromRequest<'r> for #guard_type {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
error[E0277]: the trait bound `Unknown: Poolable` is not satisfied
|
||||
--> $DIR/database-types.rs:7:10
|
||||
|
|
||||
7 | struct A(Unknown);
|
||||
| ^^^^^^^ the trait `Poolable` is not implemented for `Unknown`
|
||||
|
|
||||
::: $WORKSPACE/contrib/lib/src/databases.rs
|
||||
|
|
||||
| pub struct Connection<K, C: Poolable> {
|
||||
| -------- required by this bound in `rocket_contrib::databases::Connection`
|
||||
--> $DIR/database-types.rs:7:10
|
||||
|
|
||||
7 | struct A(Unknown);
|
||||
| ^^^^^^^ the trait `Poolable` is not implemented for `Unknown`
|
||||
|
|
||||
::: $WORKSPACE/contrib/lib/src/databases/connection.rs
|
||||
|
|
||||
| pub struct Connection<K, C: Poolable> {
|
||||
| -------- required by this bound in `rocket_contrib::databases::Connection`
|
||||
|
||||
error[E0277]: the trait bound `Vec<i32>: Poolable` is not satisfied
|
||||
--> $DIR/database-types.rs:10:10
|
||||
|
|
||||
10 | struct B(Vec<i32>);
|
||||
| ^^^^^^^^ the trait `Poolable` is not implemented for `Vec<i32>`
|
||||
|
|
||||
::: $WORKSPACE/contrib/lib/src/databases.rs
|
||||
|
|
||||
| pub struct Connection<K, C: Poolable> {
|
||||
| -------- required by this bound in `rocket_contrib::databases::Connection`
|
||||
--> $DIR/database-types.rs:10:10
|
||||
|
|
||||
10 | struct B(Vec<i32>);
|
||||
| ^^^^^^^^ the trait `Poolable` is not implemented for `Vec<i32>`
|
||||
|
|
||||
::: $WORKSPACE/contrib/lib/src/databases/connection.rs
|
||||
|
|
||||
| pub struct Connection<K, C: Poolable> {
|
||||
| -------- required by this bound in `rocket_contrib::databases::Connection`
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
error[E0277]: the trait bound `Unknown: Poolable` is not satisfied
|
||||
--> $DIR/database-types.rs:7:10
|
||||
|
|
||||
7 | struct A(Unknown);
|
||||
| ^^^^^^^ the trait `Poolable` is not implemented for `Unknown`
|
||||
|
|
||||
::: $WORKSPACE/contrib/lib/src/databases.rs
|
||||
|
|
||||
| pub struct Connection<K, C: Poolable> {
|
||||
| -------- required by this bound in `rocket_contrib::databases::Connection`
|
||||
--> $DIR/database-types.rs:7:10
|
||||
|
|
||||
7 | struct A(Unknown);
|
||||
| ^^^^^^^ the trait `Poolable` is not implemented for `Unknown`
|
||||
|
|
||||
::: $WORKSPACE/contrib/lib/src/databases/connection.rs
|
||||
|
|
||||
| pub struct Connection<K, C: Poolable> {
|
||||
| -------- required by this bound in `rocket_contrib::databases::Connection`
|
||||
|
||||
error[E0277]: the trait bound `Vec<i32>: Poolable` is not satisfied
|
||||
--> $DIR/database-types.rs:10:10
|
||||
|
|
||||
10 | struct B(Vec<i32>);
|
||||
| ^^^ the trait `Poolable` is not implemented for `Vec<i32>`
|
||||
|
|
||||
::: $WORKSPACE/contrib/lib/src/databases.rs
|
||||
|
|
||||
| pub struct Connection<K, C: Poolable> {
|
||||
| -------- required by this bound in `rocket_contrib::databases::Connection`
|
||||
--> $DIR/database-types.rs:10:10
|
||||
|
|
||||
10 | struct B(Vec<i32>);
|
||||
| ^^^ the trait `Poolable` is not implemented for `Vec<i32>`
|
||||
|
|
||||
::: $WORKSPACE/contrib/lib/src/databases/connection.rs
|
||||
|
|
||||
| pub struct Connection<K, C: Poolable> {
|
||||
| -------- 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]
|
||||
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 = ();
|
||||
|
||||
#[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>>() {
|
||||
Some(c) => c.get().await.into_outcome(Status::ServiceUnavailable),
|
||||
None => {
|
||||
|
|
|
@ -85,10 +85,10 @@ impl Metadata<'_> {
|
|||
/// an error is printed and an empty `Err` with status `InternalServerError`
|
||||
/// (`500`) is returned.
|
||||
#[rocket::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for Metadata<'a> {
|
||||
impl<'r> FromRequest<'r> for Metadata<'r> {
|
||||
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
|
||||
.succeeded()
|
||||
.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>;
|
||||
| -- 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
|
||||
|
|
||||
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
|
||||
|
|
||||
| pub trait FromRequest<'a, 'r>: Sized {
|
||||
| -- required by this bound in `from_request`
|
||||
| async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error>;
|
||||
| -- required by this bound in `from_request`
|
||||
|
||||
error[E0277]: the trait bound `Q: FromParam<'_>` is not satisfied
|
||||
--> $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`
|
||||
|
||||
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
|
||||
|
|
||||
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
|
||||
|
|
||||
| pub trait FromRequest<'a, 'r>: Sized {
|
||||
| -- required by this bound in `from_request`
|
||||
| async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error>;
|
||||
| -- required by this bound in `from_request`
|
||||
|
||||
error[E0277]: the trait bound `Q: FromParam<'_>` is not satisfied
|
||||
--> $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>;
|
||||
| -- 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
|
||||
|
|
||||
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
|
||||
|
|
||||
| pub trait FromRequest<'a, 'r>: Sized {
|
||||
| -- required by this bound in `from_request`
|
||||
| async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error>;
|
||||
| -- required by this bound in `from_request`
|
||||
|
||||
error[E0277]: the trait bound `Q: FromParam<'_>` is not satisfied
|
||||
--> $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`
|
||||
|
||||
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
|
||||
|
|
||||
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
|
||||
|
|
||||
| pub trait FromRequest<'a, 'r>: Sized {
|
||||
| -- required by this bound in `from_request`
|
||||
| async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error>;
|
||||
| -- required by this bound in `from_request`
|
||||
|
||||
error[E0277]: the trait bound `Q: FromParam<'_>` is not satisfied
|
||||
--> $DIR/route-type-errors.rs:24:18
|
||||
|
|
|
@ -380,10 +380,10 @@ impl Provider for Config {
|
|||
}
|
||||
|
||||
#[crate::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for &'r Config {
|
||||
impl<'r> FromRequest<'r> for &'r Config {
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -182,10 +182,10 @@ impl PartialEq for SecretKey {
|
|||
}
|
||||
|
||||
#[crate::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for &'a SecretKey {
|
||||
impl<'r> FromRequest<'r> for &'r SecretKey {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,10 +111,10 @@ pub use self::cookie::{Cookie, SameSite, Iter};
|
|||
/// struct User(usize);
|
||||
///
|
||||
/// #[rocket::async_trait]
|
||||
/// impl<'a, 'r> FromRequest<'a, 'r> for User {
|
||||
/// impl<'r> FromRequest<'r> for User {
|
||||
/// 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()
|
||||
/// .get_private("user_id")
|
||||
/// .and_then(|c| c.value().parse().ok())
|
||||
|
|
|
@ -300,10 +300,10 @@ impl fmt::Display for Limits {
|
|||
}
|
||||
|
||||
#[crate::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for &'r Limits {
|
||||
impl<'r> FromRequest<'r> for &'r Limits {
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -353,10 +353,10 @@ pub use self::info_kind::{Info, Kind};
|
|||
///
|
||||
/// // Allows a route to access the time a request was initiated.
|
||||
/// #[rocket::async_trait]
|
||||
/// impl<'a, 'r> FromRequest<'a, 'r> for StartTime {
|
||||
/// impl<'r> FromRequest<'r> for StartTime {
|
||||
/// 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)) {
|
||||
/// TimerStart(Some(time)) => request::Outcome::Success(StartTime(time)),
|
||||
/// 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;
|
||||
///
|
||||
/// #[rocket::async_trait]
|
||||
/// impl<'a, 'r> FromRequest<'a, 'r> for Guard1 {
|
||||
/// impl<'r> FromRequest<'r> for Guard1 {
|
||||
/// 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.
|
||||
/// let atomics = try_outcome!(req.guard::<State<'_, Atomics>>().await);
|
||||
/// 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]
|
||||
/// impl<'a, 'r> FromRequest<'a, 'r> for Guard2 {
|
||||
/// impl<'r> FromRequest<'r> for Guard2 {
|
||||
/// 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.
|
||||
/// let guard1: Guard1 = try_outcome!(req.guard::<Guard1>().await);
|
||||
/// Success(Guard2)
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
use std::fmt::Debug;
|
||||
use std::net::{IpAddr, SocketAddr};
|
||||
|
||||
use futures::future::BoxFuture;
|
||||
|
||||
use crate::router::Route;
|
||||
use crate::request::Request;
|
||||
use crate::outcome::{self, IntoOutcome};
|
||||
|
@ -60,10 +58,10 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
|||
/// # type MyError = String;
|
||||
///
|
||||
/// #[rocket::async_trait]
|
||||
/// impl<'a, 'r> FromRequest<'a, 'r> for MyType {
|
||||
/// impl<'r> FromRequest<'r> for MyType {
|
||||
/// 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!()
|
||||
/// }
|
||||
|
@ -203,42 +201,36 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
|||
/// use rocket::http::Status;
|
||||
/// use rocket::request::{self, Outcome, Request, FromRequest};
|
||||
///
|
||||
/// struct ApiKey(String);
|
||||
///
|
||||
/// /// Returns true if `key` is a valid API key string.
|
||||
/// fn is_valid(key: &str) -> bool {
|
||||
/// key == "valid_api_key"
|
||||
/// }
|
||||
/// struct ApiKey<'r>(&'r str);
|
||||
///
|
||||
/// #[derive(Debug)]
|
||||
/// enum ApiKeyError {
|
||||
/// BadCount,
|
||||
/// Missing,
|
||||
/// Invalid,
|
||||
/// }
|
||||
///
|
||||
/// #[rocket::async_trait]
|
||||
/// impl<'a, 'r> FromRequest<'a, 'r> for ApiKey {
|
||||
/// impl<'r> FromRequest<'r> for ApiKey<'r> {
|
||||
/// type Error = ApiKeyError;
|
||||
///
|
||||
/// async fn from_request(req: &'a Request<'r>) -> Outcome<Self, Self::Error> {
|
||||
/// let keys: Vec<_> = req.headers().get("x-api-key").collect();
|
||||
/// match keys.len() {
|
||||
/// 0 => Outcome::Failure((Status::BadRequest, ApiKeyError::Missing)),
|
||||
/// 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)),
|
||||
/// async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||
/// /// Returns true if `key` is a valid API key string.
|
||||
/// fn is_valid(key: &str) -> bool {
|
||||
/// key == "valid_api_key"
|
||||
/// }
|
||||
///
|
||||
/// 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")]
|
||||
/// fn sensitive(key: ApiKey) -> &'static str {
|
||||
/// # let _key = key;
|
||||
/// fn sensitive(key: ApiKey<'_>) -> &'static str {
|
||||
/// "Sensitive data."
|
||||
/// }
|
||||
///
|
||||
/// # fn main() { }
|
||||
/// ```
|
||||
///
|
||||
/// # Request-Local State
|
||||
|
@ -264,9 +256,9 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
|||
/// # }
|
||||
/// # }
|
||||
/// # #[rocket::async_trait]
|
||||
/// # impl<'a, 'r> FromRequest<'a, 'r> for Database {
|
||||
/// # impl<'r> FromRequest<'r> for Database {
|
||||
/// # type Error = ();
|
||||
/// # async fn from_request(request: &'a Request<'r>) -> Outcome<Database, ()> {
|
||||
/// # async fn from_request(request: &'r Request<'_>) -> Outcome<Database, ()> {
|
||||
/// # Outcome::Success(Database)
|
||||
/// # }
|
||||
/// # }
|
||||
|
@ -274,10 +266,10 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
|||
/// # struct Admin { user: User }
|
||||
/// #
|
||||
/// #[rocket::async_trait]
|
||||
/// impl<'a, 'r> FromRequest<'a, 'r> for User {
|
||||
/// impl<'r> FromRequest<'r> for User {
|
||||
/// 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);
|
||||
/// request.cookies()
|
||||
/// .get_private("user_id")
|
||||
|
@ -288,10 +280,10 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
|||
/// }
|
||||
///
|
||||
/// #[rocket::async_trait]
|
||||
/// impl<'a, 'r> FromRequest<'a, 'r> for Admin {
|
||||
/// impl<'r> FromRequest<'r> for Admin {
|
||||
/// 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!
|
||||
/// let user = try_outcome!(request.guard::<User>().await);
|
||||
/// if user.is_admin {
|
||||
|
@ -328,9 +320,9 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
|||
/// # }
|
||||
/// # }
|
||||
/// # #[rocket::async_trait]
|
||||
/// # impl<'a, 'r> FromRequest<'a, 'r> for Database {
|
||||
/// # impl<'r> FromRequest<'r> for Database {
|
||||
/// # type Error = ();
|
||||
/// # async fn from_request(request: &'a Request<'r>) -> Outcome<Database, ()> {
|
||||
/// # async fn from_request(request: &'r Request<'_>) -> Outcome<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 }
|
||||
/// #
|
||||
/// #[rocket::async_trait]
|
||||
/// impl<'a, 'r> FromRequest<'a, 'r> for &'a User {
|
||||
/// impl<'r> FromRequest<'r> for &'r User {
|
||||
/// 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
|
||||
/// // the number of times the `User` guard is executed.
|
||||
/// 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]
|
||||
/// impl<'a, 'r> FromRequest<'a, 'r> for Admin<'a> {
|
||||
/// impl<'r> FromRequest<'r> for Admin<'r> {
|
||||
/// 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);
|
||||
/// if user.is_admin {
|
||||
/// 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
|
||||
#[crate::async_trait]
|
||||
pub trait FromRequest<'a, 'r>: Sized {
|
||||
pub trait FromRequest<'r>: Sized {
|
||||
/// The associated error to be returned if derivation fails.
|
||||
type Error: Debug;
|
||||
|
||||
|
@ -387,32 +379,32 @@ pub trait FromRequest<'a, 'r>: Sized {
|
|||
/// the derivation fails in an unrecoverable fashion, `Failure` is returned.
|
||||
/// `Forward` is returned to indicate that the request should be forwarded
|
||||
/// 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]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for Method {
|
||||
impl<'r> FromRequest<'r> for Method {
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
#[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;
|
||||
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
#[crate::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for &'r Route {
|
||||
impl<'r> FromRequest<'r> for &'r Route {
|
||||
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() {
|
||||
Some(route) => Success(route),
|
||||
None => Forward(())
|
||||
|
@ -421,19 +413,19 @@ impl<'a, 'r> FromRequest<'a, 'r> for &'r Route {
|
|||
}
|
||||
|
||||
#[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;
|
||||
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
#[crate::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for &'a Accept {
|
||||
impl<'r> FromRequest<'r> for &'r Accept {
|
||||
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() {
|
||||
Some(accept) => Success(accept),
|
||||
None => Forward(())
|
||||
|
@ -442,10 +434,10 @@ impl<'a, 'r> FromRequest<'a, 'r> for &'a Accept {
|
|||
}
|
||||
|
||||
#[crate::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for &'a ContentType {
|
||||
impl<'r> FromRequest<'r> for &'r ContentType {
|
||||
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() {
|
||||
Some(content_type) => Success(content_type),
|
||||
None => Forward(())
|
||||
|
@ -454,10 +446,10 @@ impl<'a, 'r> FromRequest<'a, 'r> for &'a ContentType {
|
|||
}
|
||||
|
||||
#[crate::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for IpAddr {
|
||||
impl<'r> FromRequest<'r> for IpAddr {
|
||||
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() {
|
||||
Some(addr) => Success(addr),
|
||||
None => Forward(())
|
||||
|
@ -466,10 +458,10 @@ impl<'a, 'r> FromRequest<'a, 'r> for IpAddr {
|
|||
}
|
||||
|
||||
#[crate::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for SocketAddr {
|
||||
impl<'r> FromRequest<'r> for SocketAddr {
|
||||
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() {
|
||||
Some(addr) => Success(addr),
|
||||
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;
|
||||
|
||||
fn from_request<'y>(request: &'a Request<'r>) -> BoxFuture<'y, Outcome<Self, Self::Error>>
|
||||
where 'a: 'y, 'r: 'y
|
||||
{
|
||||
// TODO: FutureExt::map is a workaround (see rust-lang/rust#60658)
|
||||
use futures::future::FutureExt;
|
||||
T::from_request(request).map(|x| match x {
|
||||
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||
match T::from_request(request).await {
|
||||
Success(val) => Success(Ok(val)),
|
||||
Failure((_, e)) => Success(Err(e)),
|
||||
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;
|
||||
|
||||
fn from_request<'y>(request: &'a Request<'r>) -> BoxFuture<'y, Outcome<Self, Self::Error>>
|
||||
where 'a: 'y, 'r: 'y
|
||||
{
|
||||
// TODO: FutureExt::map is a workaround (see rust-lang/rust#60658)
|
||||
use futures::future::FutureExt;
|
||||
T::from_request(request).map(|x| match x {
|
||||
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||
match T::from_request(request).await {
|
||||
Success(val) => Success(Some(val)),
|
||||
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>>
|
||||
where T: FromRequest<'a, 'r> + 'z, 'a: 'z, 'r: 'z
|
||||
where T: FromRequest<'a> + 'z, 'a: 'z, 'r: 'z
|
||||
{
|
||||
T::from_request(self)
|
||||
}
|
||||
|
|
|
@ -237,10 +237,10 @@ impl<'a> FlashMessage<'a> {
|
|||
/// The suggested use is through an `Option` and the `FlashMessage` type alias
|
||||
/// in `request`: `Option<FlashMessage>`.
|
||||
#[crate::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for FlashMessage<'a> {
|
||||
impl<'r> FromRequest<'r> for FlashMessage<'r> {
|
||||
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.");
|
||||
req.cookies().get(FLASH_COOKIE_NAME).ok_or(()).and_then(|cookie| {
|
||||
trace_!("Flash: retrieving message: {:?}", cookie);
|
||||
|
|
|
@ -50,11 +50,11 @@ impl Shutdown {
|
|||
}
|
||||
|
||||
#[crate::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for Shutdown {
|
||||
impl<'r> FromRequest<'r> for Shutdown {
|
||||
type Error = std::convert::Infallible;
|
||||
|
||||
#[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())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,24 +53,33 @@ use crate::http::Status;
|
|||
/// # Within Request Guards
|
||||
///
|
||||
/// Because `State` is itself a request guard, managed state can be retrieved
|
||||
/// from another request guard's implementation. In the following code example,
|
||||
/// `Item` retrieves the `MyConfig` managed state in its [`FromRequest`]
|
||||
/// implementation using the [`Request::guard()`] method.
|
||||
/// from another request guard's implementation using either
|
||||
/// [`Request::guard()`] or [`Request::managed_state()`]. In the following code
|
||||
/// example, the `Item` request guard retrieves `MyConfig` from managed state:
|
||||
///
|
||||
/// ```rust
|
||||
/// use rocket::State;
|
||||
/// use rocket::request::{self, Request, FromRequest};
|
||||
/// use rocket::outcome::IntoOutcome;
|
||||
///
|
||||
/// # struct MyConfig{ user_val: String };
|
||||
/// struct Item(String);
|
||||
/// struct Item<'r>(&'r str);
|
||||
///
|
||||
/// #[rocket::async_trait]
|
||||
/// impl<'a, 'r> FromRequest<'a, 'r> for Item {
|
||||
/// impl<'r> FromRequest<'r> for Item<'r> {
|
||||
/// type Error = ();
|
||||
///
|
||||
/// async fn from_request(request: &'a Request<'r>) -> request::Outcome<Item, ()> {
|
||||
/// request.guard::<State<MyConfig>>().await
|
||||
/// .map(|my_config| Item(my_config.user_val.clone()))
|
||||
/// async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, ()> {
|
||||
/// // Using `State` as a request guard. Use `inner()` to get an `'r`.
|
||||
/// 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]
|
||||
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 = ();
|
||||
|
||||
#[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>() {
|
||||
Some(state) => Outcome::Success(State(state)),
|
||||
None => {
|
||||
|
|
|
@ -7,10 +7,10 @@ use rocket::outcome::IntoOutcome;
|
|||
struct HasContentType;
|
||||
|
||||
#[rocket::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for HasContentType {
|
||||
impl<'r> FromRequest<'r> for HasContentType {
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,10 @@ use rocket::outcome::Outcome::*;
|
|||
struct HeaderCount(usize);
|
||||
|
||||
#[rocket::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for HeaderCount {
|
||||
impl<'r> FromRequest<'r> for HeaderCount {
|
||||
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()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,10 +20,10 @@ struct Guard3;
|
|||
struct Guard4;
|
||||
|
||||
#[rocket::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for Guard1 {
|
||||
impl<'r> FromRequest<'r> for Guard1 {
|
||||
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);
|
||||
atomics.uncached.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]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for Guard2 {
|
||||
impl<'r> FromRequest<'r> for Guard2 {
|
||||
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);
|
||||
Outcome::Success(Guard2)
|
||||
}
|
||||
}
|
||||
|
||||
#[rocket::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for Guard3 {
|
||||
impl<'r> FromRequest<'r> for Guard3 {
|
||||
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);
|
||||
atomics.uncached.fetch_add(1, Ordering::Relaxed);
|
||||
req.local_cache_async(async {
|
||||
|
@ -58,10 +58,10 @@ impl<'a, 'r> FromRequest<'a, 'r> for Guard3 {
|
|||
}
|
||||
|
||||
#[rocket::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for Guard4 {
|
||||
impl<'r> FromRequest<'r> for Guard4 {
|
||||
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);
|
||||
Outcome::Success(Guard4)
|
||||
}
|
||||
|
|
|
@ -22,10 +22,10 @@ struct Login {
|
|||
struct User(usize);
|
||||
|
||||
#[rocket::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for User {
|
||||
impl<'r> FromRequest<'r> for User {
|
||||
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()
|
||||
.get_private("user_id")
|
||||
.and_then(|cookie| cookie.value().parse().ok())
|
||||
|
|
|
@ -128,10 +128,10 @@ use rocket::request::{self, Request, FromRequest};
|
|||
# struct HitCount { count: AtomicUsize }
|
||||
# type ErrorType = ();
|
||||
#[rocket::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for T {
|
||||
impl<'r> FromRequest<'r> for T {
|
||||
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 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.
|
||||
#[rocket::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for &'a RequestId {
|
||||
impl<'r> FromRequest<'r> for &'r RequestId {
|
||||
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
|
||||
// request: the first time the `RequestId` guard is used. If it is
|
||||
// requested again, `local_cache` will return the same value.
|
||||
|
|
Loading…
Reference in New Issue