mirror of https://github.com/rwf2/Rocket.git
Remove use of the 'try_trait' feature.
Add the 'try_outcome' macro to replace uses of '?' on 'Outcome'.
This commit is contained in:
parent
b95b6765e1
commit
e3c1a4ad3a
|
@ -145,7 +145,7 @@ pub fn database_attr(attr: TokenStream, input: TokenStream) -> Result<TokenStrea
|
||||||
|
|
||||||
fn from_request(request: &'a #request::Request<'r>) -> #request::Outcome<Self, ()> {
|
fn from_request(request: &'a #request::Request<'r>) -> #request::Outcome<Self, ()> {
|
||||||
use ::rocket::{Outcome, http::Status};
|
use ::rocket::{Outcome, http::Status};
|
||||||
let pool = request.guard::<::rocket::State<#pool_type>>()?;
|
let pool = ::rocket::try_outcome!(request.guard::<::rocket::State<#pool_type>>());
|
||||||
|
|
||||||
match pool.0.get() {
|
match pool.0.get() {
|
||||||
Ok(conn) => Outcome::Success(#guard_type(conn)),
|
Ok(conn) => Outcome::Success(#guard_type(conn)),
|
||||||
|
|
|
@ -143,7 +143,7 @@ impl<'a, T: Deserialize<'a>> FromData<'a> for Json<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_data(_: &Request<'_>, o: Transformed<'a, Self>) -> Outcome<Self, Self::Error> {
|
fn from_data(_: &Request<'_>, o: Transformed<'a, Self>) -> Outcome<Self, Self::Error> {
|
||||||
let string = o.borrowed()?;
|
let string = try_outcome!(o.borrowed());
|
||||||
match serde_json::from_str(&string) {
|
match serde_json::from_str(&string) {
|
||||||
Ok(v) => Success(Json(v)),
|
Ok(v) => Success(Json(v)),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
|
@ -131,7 +131,7 @@ impl<'a, T: Deserialize<'a>> FromData<'a> for MsgPack<T> {
|
||||||
fn from_data(_: &Request<'_>, o: Transformed<'a, Self>) -> Outcome<Self, Self::Error> {
|
fn from_data(_: &Request<'_>, o: Transformed<'a, Self>) -> Outcome<Self, Self::Error> {
|
||||||
use self::Error::*;
|
use self::Error::*;
|
||||||
|
|
||||||
let buf = o.borrowed()?;
|
let buf = try_outcome!(o.borrowed());
|
||||||
match rmp_serde::from_slice(&buf) {
|
match rmp_serde::from_slice(&buf) {
|
||||||
Ok(val) => Success(MsgPack(val)),
|
Ok(val) => Success(MsgPack(val)),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
|
@ -219,7 +219,7 @@ pub type Transformed<'a, T> =
|
||||||
/// // Retrieve a borrow to the now transformed `String` (an &str). This
|
/// // Retrieve a borrow to the now transformed `String` (an &str). This
|
||||||
/// // is only correct because we know we _always_ return a `Borrowed` from
|
/// // is only correct because we know we _always_ return a `Borrowed` from
|
||||||
/// // `transform` above.
|
/// // `transform` above.
|
||||||
/// let string = outcome.borrowed()?;
|
/// let string = try_outcome!(outcome.borrowed());
|
||||||
///
|
///
|
||||||
/// // Perform a crude, inefficient parse.
|
/// // Perform a crude, inefficient parse.
|
||||||
/// let splits: Vec<&str> = string.split(" ").collect();
|
/// let splits: Vec<&str> = string.split(" ").collect();
|
||||||
|
@ -370,16 +370,17 @@ pub trait FromData<'a>: Sized {
|
||||||
/// following:
|
/// following:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
/// # #[macro_use] extern crate rocket;
|
||||||
/// # use rocket::data::{Data, FromData, Transformed, Outcome};
|
/// # use rocket::data::{Data, FromData, Transformed, Outcome};
|
||||||
/// # fn f<'a>(outcome: Transformed<'a, Data>) -> Outcome<Data, <Data as FromData<'a>>::Error> {
|
/// # fn f<'a>(outcome: Transformed<'a, Data>) -> Outcome<Data, <Data as FromData<'a>>::Error> {
|
||||||
/// // If `Owned` was returned from `transform`:
|
/// // If `Owned` was returned from `transform`:
|
||||||
/// let data = outcome.owned()?;
|
/// let data = try_outcome!(outcome.owned());
|
||||||
/// # unimplemented!()
|
/// # unimplemented!()
|
||||||
/// # }
|
/// # }
|
||||||
///
|
///
|
||||||
/// # fn g<'a>(outcome: Transformed<'a, Data>) -> Outcome<Data, <Data as FromData<'a>>::Error> {
|
/// # fn g<'a>(outcome: Transformed<'a, Data>) -> Outcome<Data, <Data as FromData<'a>>::Error> {
|
||||||
/// // If `Borrowed` was returned from `transform`:
|
/// // If `Borrowed` was returned from `transform`:
|
||||||
/// let data = outcome.borrowed()?;
|
/// let data = try_outcome!(outcome.borrowed());
|
||||||
/// # unimplemented!()
|
/// # unimplemented!()
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -399,7 +400,7 @@ impl<'f> FromData<'f> for Data {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn from_data(_: &Request<'_>, outcome: Transformed<'f, Self>) -> Outcome<Self, Self::Error> {
|
fn from_data(_: &Request<'_>, outcome: Transformed<'f, Self>) -> Outcome<Self, Self::Error> {
|
||||||
Success(outcome.owned()?)
|
outcome.owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,7 +518,7 @@ impl<'a, T: FromDataSimple> FromData<'a> for T {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn from_data(req: &Request<'_>, o: Transformed<'a, Self>) -> Outcome<Self, Self::Error> {
|
fn from_data(req: &Request<'_>, o: Transformed<'a, Self>) -> Outcome<Self, Self::Error> {
|
||||||
T::from_data(req, o.owned()?)
|
T::from_data(req, try_outcome!(o.owned()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#![feature(try_trait)]
|
|
||||||
#![feature(proc_macro_hygiene)]
|
#![feature(proc_macro_hygiene)]
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
|
|
||||||
|
@ -95,16 +94,19 @@
|
||||||
//! [testing chapter of the guide]: https://rocket.rs/v0.5/guide/testing/#testing
|
//! [testing chapter of the guide]: https://rocket.rs/v0.5/guide/testing/#testing
|
||||||
|
|
||||||
#[allow(unused_imports)] #[macro_use] extern crate rocket_codegen;
|
#[allow(unused_imports)] #[macro_use] extern crate rocket_codegen;
|
||||||
|
// FIXME(rustdoc): We should be able to doc(inline) and not doc the
|
||||||
|
// rocket_codegen crate at all. Alas, doc-inlining will currently 1) show hidden
|
||||||
|
// proc-macros, and 2) result in proc-macros pointing to the wrong docs.
|
||||||
#[doc(hidden)] pub use rocket_codegen::*;
|
#[doc(hidden)] pub use rocket_codegen::*;
|
||||||
|
|
||||||
#[macro_use] extern crate log;
|
#[macro_use] extern crate log;
|
||||||
#[macro_use] extern crate pear;
|
#[macro_use] extern crate pear;
|
||||||
|
|
||||||
#[doc(hidden)] #[macro_use] pub mod logger;
|
#[doc(hidden)] #[macro_use] pub mod logger;
|
||||||
|
#[macro_use] pub mod outcome;
|
||||||
pub mod local;
|
pub mod local;
|
||||||
pub mod request;
|
pub mod request;
|
||||||
pub mod response;
|
pub mod response;
|
||||||
pub mod outcome;
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod data;
|
pub mod data;
|
||||||
pub mod handler;
|
pub mod handler;
|
||||||
|
|
|
@ -79,7 +79,6 @@
|
||||||
//! `None`.
|
//! `None`.
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::Try;
|
|
||||||
|
|
||||||
use yansi::{Paint, Color};
|
use yansi::{Paint, Color};
|
||||||
|
|
||||||
|
@ -601,28 +600,68 @@ impl<S, E, F> Outcome<S, E, F> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, E, F> Try for Outcome<S, E, F> {
|
/// Unwraps an [`Outcome`] to its success value, otherwise propagating the
|
||||||
type Ok = S;
|
/// forward or failure.
|
||||||
type Error = Result<F, E>;
|
///
|
||||||
|
/// In the case of a `Forward` or `Failure` variant, the inner type is passed to
|
||||||
fn into_result(self) -> Result<Self::Ok, Self::Error> {
|
/// [`From`](std::convert::From), allowing for the conversion between specific
|
||||||
match self {
|
/// and more general types. The resulting forward/error is immediately returned.
|
||||||
Success(val) => Ok(val),
|
///
|
||||||
Forward(val) => Err(Ok(val)),
|
/// Because of the early return, `try_outcome!` can only be used in methods that
|
||||||
Failure(val) => Err(Err(val)),
|
/// return [`Outcome`].
|
||||||
}
|
///
|
||||||
}
|
/// ## Example
|
||||||
|
///
|
||||||
fn from_error(val: Self::Error) -> Self {
|
/// ```rust,no_run
|
||||||
match val {
|
/// # #![feature(proc_macro_hygiene)]
|
||||||
Ok(val) => Forward(val),
|
/// # #[macro_use] extern crate rocket;
|
||||||
Err(val) => Failure(val),
|
/// # use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
}
|
/// use rocket::request::{self, Request, FromRequest, State};
|
||||||
}
|
/// use rocket::outcome::Outcome::*;
|
||||||
|
///
|
||||||
fn from_ok(val: Self::Ok) -> Self {
|
/// #[derive(Default)]
|
||||||
Success(val)
|
/// struct Atomics {
|
||||||
}
|
/// uncached: AtomicUsize,
|
||||||
|
/// cached: AtomicUsize,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// struct Guard1;
|
||||||
|
/// struct Guard2;
|
||||||
|
///
|
||||||
|
/// impl<'a, 'r> FromRequest<'a, 'r> for Guard1 {
|
||||||
|
/// type Error = ();
|
||||||
|
///
|
||||||
|
/// fn from_request(req: &'a Request<'r>) -> request::Outcome<Self, ()> {
|
||||||
|
/// // Attempt to fetch the guard, passing through any error or forward.
|
||||||
|
/// let atomics = try_outcome!(req.guard::<State<'_, Atomics>>());
|
||||||
|
/// atomics.uncached.fetch_add(1, Ordering::Relaxed);
|
||||||
|
/// req.local_cache(|| atomics.cached.fetch_add(1, Ordering::Relaxed));
|
||||||
|
///
|
||||||
|
/// Success(Guard1)
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// impl<'a, 'r> FromRequest<'a, 'r> for Guard2 {
|
||||||
|
/// type Error = ();
|
||||||
|
///
|
||||||
|
/// fn from_request(req: &'a Request<'r>) -> request::Outcome<Self, ()> {
|
||||||
|
/// // Attempt to fetch the guard, passing through any error or forward.
|
||||||
|
/// let guard1: Guard1 = try_outcome!(req.guard::<Guard1>());
|
||||||
|
/// Success(Guard2)
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! try_outcome {
|
||||||
|
($expr:expr $(,)?) => (match $expr {
|
||||||
|
$crate::outcome::Outcome::Success(val) => val,
|
||||||
|
$crate::outcome::Outcome::Failure(e) => {
|
||||||
|
return $crate::outcome::Outcome::Failure(::std::convert::From::from(e))
|
||||||
|
},
|
||||||
|
$crate::outcome::Outcome::Forward(f) => {
|
||||||
|
return $crate::outcome::Outcome::Forward(::std::convert::From::from(f))
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, E, F> fmt::Debug for Outcome<S, E, F> {
|
impl<S, E, F> fmt::Debug for Outcome<S, E, F> {
|
||||||
|
|
|
@ -211,7 +211,7 @@ impl<'f, T: FromForm<'f>> FromData<'f> for Form<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_data(_: &Request<'_>, o: Transformed<'f, Self>) -> Outcome<Self, Self::Error> {
|
fn from_data(_: &Request<'_>, o: Transformed<'f, Self>) -> Outcome<Self, Self::Error> {
|
||||||
<Form<T>>::from_data(o.borrowed()?, true).map(Form)
|
<Form<T>>::from_data(try_outcome!(o.borrowed()), true).map(Form)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ impl<'f, T: FromForm<'f>> FromData<'f> for LenientForm<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_data(_: &Request<'_>, o: Transformed<'f, Self>) -> Outcome<Self, Self::Error> {
|
fn from_data(_: &Request<'_>, o: Transformed<'f, Self>) -> Outcome<Self, Self::Error> {
|
||||||
<Form<T>>::from_data(o.borrowed()?, false).map(LenientForm)
|
<Form<T>>::from_data(try_outcome!(o.borrowed()), false).map(LenientForm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -245,7 +245,7 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
||||||
/// type Error = ();
|
/// type Error = ();
|
||||||
///
|
///
|
||||||
/// fn from_request(request: &Request<'_>) -> request::Outcome<User, ()> {
|
/// fn from_request(request: &Request<'_>) -> request::Outcome<User, ()> {
|
||||||
/// let db = request.guard::<Database>()?;
|
/// let db = try_outcome!(request.guard::<Database>());
|
||||||
/// 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())
|
||||||
|
@ -259,7 +259,7 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
||||||
///
|
///
|
||||||
/// fn from_request(request: &Request<'_>) -> request::Outcome<Admin, ()> {
|
/// fn from_request(request: &Request<'_>) -> request::Outcome<Admin, ()> {
|
||||||
/// // This will unconditionally query the database!
|
/// // This will unconditionally query the database!
|
||||||
/// let user = request.guard::<User>()?;
|
/// let user = try_outcome!(request.guard::<User>());
|
||||||
///
|
///
|
||||||
/// if user.is_admin {
|
/// if user.is_admin {
|
||||||
/// Outcome::Success(Admin { user })
|
/// Outcome::Success(Admin { user })
|
||||||
|
@ -326,7 +326,7 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
||||||
/// type Error = std::convert::Infallible;
|
/// type Error = std::convert::Infallible;
|
||||||
///
|
///
|
||||||
/// fn from_request(request: &'a Request<'_>) -> request::Outcome<Self, Self::Error> {
|
/// fn from_request(request: &'a Request<'_>) -> request::Outcome<Self, Self::Error> {
|
||||||
/// let user = request.guard::<&User>()?;
|
/// let user = try_outcome!(request.guard::<&User>());
|
||||||
///
|
///
|
||||||
/// if user.is_admin {
|
/// if user.is_admin {
|
||||||
/// Outcome::Success(Admin { user })
|
/// Outcome::Success(Admin { user })
|
||||||
|
|
|
@ -6,7 +6,7 @@ mod tests;
|
||||||
use std::{io, env};
|
use std::{io, env};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
|
||||||
use rocket::{Request, Handler, Route, Data, Catcher};
|
use rocket::{Request, Handler, Route, Data, Catcher, try_outcome};
|
||||||
use rocket::http::{Status, RawStr};
|
use rocket::http::{Status, RawStr};
|
||||||
use rocket::response::{self, Responder, status::Custom};
|
use rocket::response::{self, Responder, status::Custom};
|
||||||
use rocket::handler::Outcome;
|
use rocket::handler::Outcome;
|
||||||
|
@ -30,10 +30,11 @@ fn name<'a>(req: &'a Request, _: Data) -> Outcome<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn echo_url<'r>(req: &'r Request, _: Data) -> Outcome<'r> {
|
fn echo_url<'r>(req: &'r Request, _: Data) -> Outcome<'r> {
|
||||||
let param = req.get_param::<&RawStr>(1)
|
let param_outcome = req.get_param::<&RawStr>(1)
|
||||||
.and_then(|res| res.ok())
|
.and_then(|res| res.ok())
|
||||||
.into_outcome(Status::BadRequest)?;
|
.into_outcome(Status::BadRequest);
|
||||||
|
|
||||||
|
let param = try_outcome!(param_outcome);
|
||||||
Outcome::try_from(req, RawStr::from_str(param).url_decode())
|
Outcome::try_from(req, RawStr::from_str(param).url_decode())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,10 +80,11 @@ impl CustomHandler {
|
||||||
|
|
||||||
impl Handler for CustomHandler {
|
impl Handler for CustomHandler {
|
||||||
fn handle<'r>(&self, req: &'r Request, data: Data) -> Outcome<'r> {
|
fn handle<'r>(&self, req: &'r Request, data: Data) -> Outcome<'r> {
|
||||||
let id = req.get_param::<&RawStr>(0)
|
let id_outcome = req.get_param::<&RawStr>(0)
|
||||||
.and_then(|res| res.ok())
|
.and_then(|res| res.ok())
|
||||||
.or_forward(data)?;
|
.or_forward(data);
|
||||||
|
|
||||||
|
let id = try_outcome!(id_outcome);
|
||||||
Outcome::from(req, format!("{} - {}", self.data, id))
|
Outcome::from(req, format!("{} - {}", self.data, id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for Guard1 {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
fn from_request(req: &'a Request<'r>) -> request::Outcome<Self, ()> {
|
fn from_request(req: &'a Request<'r>) -> request::Outcome<Self, ()> {
|
||||||
let atomics = req.guard::<State<'_, Atomics>>()?;
|
let atomics = try_outcome!(req.guard::<State<'_, Atomics>>());
|
||||||
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));
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for Guard2 {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
fn from_request(req: &'a Request<'r>) -> request::Outcome<Self, ()> {
|
fn from_request(req: &'a Request<'r>) -> request::Outcome<Self, ()> {
|
||||||
req.guard::<Guard1>()?;
|
try_outcome!(req.guard::<Guard1>());
|
||||||
Success(Guard2)
|
Success(Guard2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue