Skip to content

Commit

Permalink
Document 'async' attributes.
Browse files Browse the repository at this point in the history
  • Loading branch information
SergioBenitez committed Apr 29, 2021
1 parent ad8d809 commit fe23eae
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 3 deletions.
91 changes: 90 additions & 1 deletion core/codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
//!
Expand Down Expand Up @@ -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<Build>`.
///
/// When applied to a function that returns a `Rocket<Build>` 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<Build> {
/// rocket::build()
/// }
/// ```
///
/// This generates code equivalent to the following:
///
/// ```rust,no_run
/// # use rocket::{Rocket, Build};
/// # fn rocket() -> Rocket<Build> {
/// # 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<Build>`:
///
/// ```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))
Expand Down
25 changes: 24 additions & 1 deletion core/lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,30 @@ pub fn custom<T: figment::Provider>(provider: T) -> Rocket<Build> {

/// 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;

Expand Down
3 changes: 2 additions & 1 deletion core/lib/src/rocket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down

0 comments on commit fe23eae

Please sign in to comment.