diff --git a/core/codegen/src/lib.rs b/core/codegen/src/lib.rs index efcef0051d..a15290253b 100644 --- a/core/codegen/src/lib.rs +++ b/core/codegen/src/lib.rs @@ -4,7 +4,7 @@ #![doc(html_favicon_url = "https://rocket.rs/images/favicon.ico")] #![doc(html_logo_url = "https://rocket.rs/images/logo-boxed.png")] -#![warn(rust_2018_idioms)] +#![warn(rust_2018_idioms, missing_docs)] //! # Rocket - Code Generation //! @@ -377,11 +377,100 @@ pub fn async_test(args: TokenStream, input: TokenStream) -> TokenStream { emit!(attribute::entry::async_test_attribute(args, input)) } +/// Retrofits `async fn` support in `main` functions. +/// +/// A `main` `async fn` function decorated with `#[rocket::main]` is transformed +/// into a regular `main` function that internally initalizes a Rocket-specific +/// tokio runtime and runs the attributed `async fn` inside of it: +/// +/// ```rust,no_run +/// #[rocket::main] +/// async fn main() -> Result<(), rocket::Error> { +/// rocket::build() +/// .ignite().await? +/// .launch().await +/// } +/// ``` +/// +/// It should be used only when inspection of an ignited instance of `Rocket` is +/// required, or when the return value of `launch()` is to be inspected: +/// +/// ```rust,no_run +/// #[rocket::main] +/// async fn main() -> Result<(), rocket::Error> { +/// let rocket = rocket::build().ignite().await?; +/// println!("Hello, Rocket: {:?}", rocket); +/// +/// let result = rocket.launch().await; +/// println!("The server shutdown: {:?}", result); +/// +/// result +/// } +/// ``` +/// +/// For all other cases, use [`#[launch]`](launch) instead. +/// +/// The function attributed with `#[rocket::main]` _must_ be `async` and _must_ +/// be called `main`. Violation of either results in a compile-time error. #[proc_macro_attribute] pub fn main(args: TokenStream, input: TokenStream) -> TokenStream { emit!(attribute::entry::main_attribute(args, input)) } +/// Generates a `main` function that launches a returned `Rocket`. +/// +/// When applied to a function that returns a `Rocket` instance, +/// `#[launch]` automatically initializes an `async` runtime and +/// launches the function's returned instance: +/// +/// ```rust,no_run +/// # use rocket::launch; +/// use rocket::{Rocket, Build}; +/// +/// #[launch] +/// fn rocket() -> Rocket { +/// rocket::build() +/// } +/// ``` +/// +/// This generates code equivalent to the following: +/// +/// ```rust,no_run +/// # use rocket::{Rocket, Build}; +/// # fn rocket() -> Rocket { +/// # rocket::build() +/// # } +/// # +/// #[rocket::main] +/// async fn main() { +/// // Recall that an uninspected `Error` will cause a pretty-printed panic, +/// // so rest assured failures do not go undetected when using `#[launch]`. +/// let _ = rocket().launch().await; +/// } +/// ``` +/// +/// To avoid needing to import _any_ items in the common case, the `launch` +/// attribute will infer a return type written as `_` as `Rocket`: +/// +/// ```rust,no_run +/// # use rocket::launch; +/// #[launch] +/// fn rocket() -> _ { +/// rocket::build() +/// } +/// ``` +/// +/// The attributed function may be `async`: +/// +/// ```rust,no_run +/// # use rocket::launch; +/// # async fn some_async_work() {} +/// #[launch] +/// async fn rocket() -> _ { +/// some_async_work().await; +/// rocket::build() +/// } +/// ``` #[proc_macro_attribute] pub fn launch(args: TokenStream, input: TokenStream) -> TokenStream { emit!(attribute::entry::launch_attribute(args, input)) diff --git a/core/lib/src/lib.rs b/core/lib/src/lib.rs index 647168ad37..cf64ecf8e3 100644 --- a/core/lib/src/lib.rs +++ b/core/lib/src/lib.rs @@ -179,7 +179,30 @@ pub fn custom(provider: T) -> Rocket { /// Retrofits support for `async fn` in trait impls and declarations. /// -/// See [`async_trait`](mod@async_trait) for full details. +/// Any trait declaration or trait `impl` decorated with `#[async_trait]` is +/// retrofitted with support for `async fn`s: +/// +/// ```rust +/// # use rocket::*; +/// #[async_trait] +/// trait MyAsyncTrait { +/// async fn do_async_work(); +/// } +/// +/// #[async_trait] +/// impl MyAsyncTrait for () { +/// async fn do_async_work() { /* .. */ } +/// } +/// ``` +/// +/// All `impl`s for a trait declared with `#[async_trait]` must themselves be +/// decorated with `#[async_trait]`. Many of Rocket's traits, such as +/// [`FromRequest`](crate::request::FromRequest) and +/// [`Fairing`](crate::fairing::Fairing) are `async`. As such, implementations +/// of said traits must be decorated with `#[async_trait]`. See the individual +/// trait docs for trait-specific details. +/// +/// For more details on `#[async_trait]`, see [`async_trait`](mod@async_trait). #[doc(inline)] pub use async_trait::async_trait; diff --git a/core/lib/src/rocket.rs b/core/lib/src/rocket.rs index f14d9ded0b..bd12c71fef 100644 --- a/core/lib/src/rocket.rs +++ b/core/lib/src/rocket.rs @@ -54,7 +54,8 @@ use crate::log::PaintExt; /// To launch an instance of `Rocket`, it _must_ progress through all three /// phases. To progress into the ignite or launch phases, a tokio `async` /// runtime is required. The [`#[main]`](crate::main) attribute initializes a -/// Rocket-specific tokio runtime and runs attributed async code inside of it: +/// Rocket-specific tokio runtime and runs the attributed `async fn` inside of +/// it: /// /// ```rust,no_run /// #[rocket::main]