From e7b28f18a9cec7a80a552b4867710e73cb5c1442 Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Wed, 28 Apr 2021 01:41:13 -0700 Subject: [PATCH] Doc 'form' items, 'async_test', private macros. --- core/codegen/src/lib.rs | 19 +++++++++++++++++++ core/codegen/tests/route.rs | 4 +++- core/lib/src/form/context.rs | 24 +++++------------------- core/lib/src/form/error.rs | 12 ++++++++---- core/lib/src/lib.rs | 14 +++++++------- core/lib/src/outcome.rs | 3 +++ core/lib/src/response/status.rs | 2 -- 7 files changed, 45 insertions(+), 33 deletions(-) diff --git a/core/codegen/src/lib.rs b/core/codegen/src/lib.rs index 682c15c9..a59cb647 100644 --- a/core/codegen/src/lib.rs +++ b/core/codegen/src/lib.rs @@ -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)) } diff --git a/core/codegen/tests/route.rs b/core/codegen/tests/route.rs index 3998b0d7..f02d285c 100644 --- a/core/codegen/tests/route.rs +++ b/core/codegen/tests/route.rs @@ -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().mount("/", rocket::routes![hello, world]) + rocket::build().mount("/", rocket::routes![hello, world, other::world]) } } diff --git a/core/lib/src/form/context.rs b/core/lib/src/form/context.rs index c01dd01d..bacfea93 100644 --- a/core/lib/src/form/context.rs +++ b/core/lib/src/form/context.rs @@ -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, + /// The context containig all received fields, values, and errors. pub context: Context<'v> } @@ -101,25 +106,6 @@ impl<'f> From> for Context<'f> { } } -// impl<'v, T> From> 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 { -// match Form::>::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 = (>::Context, Context<'v>); diff --git a/core/lib/src/form/error.rs b/core/lib/src/form/error.rs index 02acc19e..24026808 100644 --- a/core/lib/src/form/error.rs +++ b/core/lib/src/form/error.rs @@ -59,15 +59,19 @@ pub struct Errors<'v>(Vec>); /// 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 diff --git a/core/lib/src/lib.rs b/core/lib/src/lib.rs index c5c9b2e6..a0d31021 100644 --- a/core/lib/src/lib.rs +++ b/core/lib/src/lib.rs @@ -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(provider: T) -> Rocket { 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(fut: impl std::future::Future + Send) -> R { diff --git a/core/lib/src/outcome.rs b/core/lib/src/outcome.rs index 59a38f5e..d050ec98 100644 --- a/core/lib/src/outcome.rs +++ b/core/lib/src/outcome.rs @@ -606,6 +606,9 @@ impl Outcome { } } impl<'a, S: Send + 'a, E: Send + 'a, F: Send + 'a> Outcome { + /// 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 }) diff --git a/core/lib/src/response/status.rs b/core/lib/src/response/status.rs index b521a150..e995dbf7 100644 --- a/core/lib/src/response/status.rs +++ b/core/lib/src/response/status.rs @@ -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