Doc 'form' items, 'async_test', private macros.

This commit is contained in:
Sergio Benitez 2021-04-28 01:41:13 -07:00
parent fd36a6d7fe
commit e7b28f18a9
7 changed files with 45 additions and 33 deletions

View File

@ -355,6 +355,23 @@ pub fn catch(args: TokenStream, input: TokenStream) -> TokenStream {
emit!(attribute::catch::catch_attribute(args, input))
}
/// Retrofits supports for `async fn` in unit tests.
///
/// Simply decorate a test `async fn` with `#[async_test]` instead of `#[test]`:
///
/// ```rust
/// # #[macro_use] extern crate rocket;
/// #[cfg(test)]
/// mod tests {
/// #[async_test]
/// async fn test() {
/// /* .. */
/// }
/// }
/// ```
///
/// The attribute rewrites the function to execute inside of a Rocket-compatible
/// async runtime.
#[proc_macro_attribute]
pub fn async_test(args: TokenStream, input: TokenStream) -> TokenStream {
emit!(attribute::entry::async_test_attribute(args, input))
@ -1053,12 +1070,14 @@ pub fn uri(input: TokenStream) -> TokenStream {
#[doc(hidden)]
#[proc_macro]
/// Internal macro: `rocket_internal_uri!`.
pub fn rocket_internal_uri(input: TokenStream) -> TokenStream {
emit!(bang::uri_internal_macro(input))
}
#[doc(hidden)]
#[proc_macro]
/// Private Rocket internal macro: `internal_guide_tests!`.
pub fn internal_guide_tests(input: TokenStream) -> TokenStream {
emit!(bang::guide_tests_internal(input))
}

View File

@ -130,6 +130,8 @@ fn test_full_route() {
}
mod scopes {
#![allow(dead_code)]
mod other {
#[get("/world")]
pub fn world() -> &'static str {
@ -145,7 +147,7 @@ mod scopes {
use other::world;
fn _rocket() -> rocket::Rocket<rocket::Build> {
rocket::build().mount("/", rocket::routes![hello, world])
rocket::build().mount("/", rocket::routes![hello, world, other::world])
}
}

View File

@ -6,9 +6,14 @@ use crate::http::Status;
/// An infallible form guard that records form fields while parsing any form
/// type.
///
/// See the [forms guide](https://rocket.rs/master/guide/requests/#context) for
/// usage details.
#[derive(Debug)]
pub struct Contextual<'v, T> {
/// The value, if it could be successfully parsed.
pub value: Option<T>,
/// The context containig all received fields, values, and errors.
pub context: Context<'v>
}
@ -101,25 +106,6 @@ impl<'f> From<Errors<'f>> for Context<'f> {
}
}
// impl<'v, T> From<Errors<'v>> for Contextual<'v, T> {
// fn from(e: Errors<'v>) -> Self {
// Contextual { value: None, context: Context::from(e) }
// }
// }
// #[crate::async_trait]
// impl<'r, T: FromForm<'r>> FromData<'r> for Contextual<'r, T> {
// type Error = std::convert::Infallible;
//
// async fn from_data(req: &'r Request<'_>, data: Data) -> Outcome<Self, Self::Error> {
// match Form::<Contextual<'r, T>>::from_data(req, data).await {
// Outcome::Success(form) => Outcome::Success(form.into_inner()),
// Outcome::Failure((_, e)) => Outcome::Success(Contextual::from(e)),
// Outcome::Forward(d) => Outcome::Forward(d)
// }
// }
// }
#[crate::async_trait]
impl<'v, T: FromForm<'v>> FromForm<'v> for Contextual<'v, T> {
type Context = (<T as FromForm<'v>>::Context, Context<'v>);

View File

@ -59,15 +59,19 @@ pub struct Errors<'v>(Vec<Error<'v>>);
/// A form error, potentially tied to a specific form field.
///
/// An `Error` is returned by [`FromForm`], [`FromFormField`], and
/// [`validate`](crate::form::validate) procedures, typically as a collection of
/// [`Errors`]. It potentially identifies a specific field that triggered the
/// error via [`Error::name`] and the field's value via [`Error::value`].
/// An `Error` is returned by [`FromForm`], [`FromFormField`], and [`validate`]
/// procedures, typically as a collection of [`Errors`]. It potentially
/// identifies a specific field that triggered the error via [`Error::name`] and
/// the field's value via [`Error::value`].
///
/// An `Error` can occur because of a field's value that failed to parse or
/// because other parts of a field or form were malformed; the [`Error::entity`]
/// identifies the part of the form that resulted in the error.
///
/// [`FromForm`]: crate::form::FromForm
/// [`FromFormField`]: crate::form::FromFormField
/// [`validate`]: crate::form::validate
///
/// # Contructing
///
/// An `Error` can be constructed from anything that an [`ErrorKind`] can be

View File

@ -102,13 +102,6 @@
//!
//! [testing chapter of the guide]: https://rocket.rs/master/guide/testing/#testing
#[macro_use]
#[allow(unused_imports)]
extern crate rocket_codegen;
pub use rocket_codegen::*;
pub use async_trait::*;
/// These are public dependencies! Update docs if these are changed, especially
/// figment's version number in docs.
#[doc(hidden)]
@ -164,6 +157,7 @@ mod phase;
#[doc(inline)] pub use phase::{Phase, Build, Ignite, Orbit};
#[doc(inline)] pub use error::Error;
#[doc(inline)] pub use sentinel::Sentinel;
#[doc(inline)] pub use rocket_codegen::*;
pub use crate::rocket::Rocket;
pub use crate::request::Request;
pub use crate::shutdown::Shutdown;
@ -181,6 +175,12 @@ pub fn custom<T: figment::Provider>(provider: T) -> Rocket<Build> {
Rocket::custom(provider)
}
/// Retrofits support for `async fn` in trait impls and declarations.
///
/// See [`async_trait`](mod@async_trait) for full details.
#[doc(inline)]
pub use async_trait::async_trait;
/// WARNING: This is unstable! Do not use this method outside of Rocket!
#[doc(hidden)]
pub fn async_test<R>(fut: impl std::future::Future<Output = R> + Send) -> R {

View File

@ -606,6 +606,9 @@ impl<S, E, F> Outcome<S, E, F> {
}
}
impl<'a, S: Send + 'a, E: Send + 'a, F: Send + 'a> Outcome<S, E, F> {
/// Pins a future that resolves to `self`, returning a
/// [`BoxFuture`](crate::futures::future::BoxFuture) that resolves to
/// `self`.
#[inline]
pub fn pin(self) -> futures::future::BoxFuture<'a, Self> {
Box::pin(async move { self })

View File

@ -9,8 +9,6 @@
//! responders; when they do, the responder finalizes the response by writing
//! out additional headers and, importantly, the body of the response.
//!
//!
//!
//! The [`Custom`] type allows responding with _any_ `Status` but _does not_
//! ensure that all of the required headers are present. As a convenience,
//! `(Status, R)` where `R: Responder` is _also_ a `Responder`, identical to