Skip to content

Commit fe23eae

Browse files
committed
Document 'async' attributes.
1 parent ad8d809 commit fe23eae

File tree

3 files changed

+116
-3
lines changed

3 files changed

+116
-3
lines changed

core/codegen/src/lib.rs

+90-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#![doc(html_favicon_url = "https://rocket.rs/images/favicon.ico")]
55
#![doc(html_logo_url = "https://rocket.rs/images/logo-boxed.png")]
66

7-
#![warn(rust_2018_idioms)]
7+
#![warn(rust_2018_idioms, missing_docs)]
88

99
//! # Rocket - Code Generation
1010
//!
@@ -377,11 +377,100 @@ pub fn async_test(args: TokenStream, input: TokenStream) -> TokenStream {
377377
emit!(attribute::entry::async_test_attribute(args, input))
378378
}
379379

380+
/// Retrofits `async fn` support in `main` functions.
381+
///
382+
/// A `main` `async fn` function decorated with `#[rocket::main]` is transformed
383+
/// into a regular `main` function that internally initalizes a Rocket-specific
384+
/// tokio runtime and runs the attributed `async fn` inside of it:
385+
///
386+
/// ```rust,no_run
387+
/// #[rocket::main]
388+
/// async fn main() -> Result<(), rocket::Error> {
389+
/// rocket::build()
390+
/// .ignite().await?
391+
/// .launch().await
392+
/// }
393+
/// ```
394+
///
395+
/// It should be used only when inspection of an ignited instance of `Rocket` is
396+
/// required, or when the return value of `launch()` is to be inspected:
397+
///
398+
/// ```rust,no_run
399+
/// #[rocket::main]
400+
/// async fn main() -> Result<(), rocket::Error> {
401+
/// let rocket = rocket::build().ignite().await?;
402+
/// println!("Hello, Rocket: {:?}", rocket);
403+
///
404+
/// let result = rocket.launch().await;
405+
/// println!("The server shutdown: {:?}", result);
406+
///
407+
/// result
408+
/// }
409+
/// ```
410+
///
411+
/// For all other cases, use [`#[launch]`](launch) instead.
412+
///
413+
/// The function attributed with `#[rocket::main]` _must_ be `async` and _must_
414+
/// be called `main`. Violation of either results in a compile-time error.
380415
#[proc_macro_attribute]
381416
pub fn main(args: TokenStream, input: TokenStream) -> TokenStream {
382417
emit!(attribute::entry::main_attribute(args, input))
383418
}
384419

420+
/// Generates a `main` function that launches a returned `Rocket<Build>`.
421+
///
422+
/// When applied to a function that returns a `Rocket<Build>` instance,
423+
/// `#[launch]` automatically initializes an `async` runtime and
424+
/// launches the function's returned instance:
425+
///
426+
/// ```rust,no_run
427+
/// # use rocket::launch;
428+
/// use rocket::{Rocket, Build};
429+
///
430+
/// #[launch]
431+
/// fn rocket() -> Rocket<Build> {
432+
/// rocket::build()
433+
/// }
434+
/// ```
435+
///
436+
/// This generates code equivalent to the following:
437+
///
438+
/// ```rust,no_run
439+
/// # use rocket::{Rocket, Build};
440+
/// # fn rocket() -> Rocket<Build> {
441+
/// # rocket::build()
442+
/// # }
443+
/// #
444+
/// #[rocket::main]
445+
/// async fn main() {
446+
/// // Recall that an uninspected `Error` will cause a pretty-printed panic,
447+
/// // so rest assured failures do not go undetected when using `#[launch]`.
448+
/// let _ = rocket().launch().await;
449+
/// }
450+
/// ```
451+
///
452+
/// To avoid needing to import _any_ items in the common case, the `launch`
453+
/// attribute will infer a return type written as `_` as `Rocket<Build>`:
454+
///
455+
/// ```rust,no_run
456+
/// # use rocket::launch;
457+
/// #[launch]
458+
/// fn rocket() -> _ {
459+
/// rocket::build()
460+
/// }
461+
/// ```
462+
///
463+
/// The attributed function may be `async`:
464+
///
465+
/// ```rust,no_run
466+
/// # use rocket::launch;
467+
/// # async fn some_async_work() {}
468+
/// #[launch]
469+
/// async fn rocket() -> _ {
470+
/// some_async_work().await;
471+
/// rocket::build()
472+
/// }
473+
/// ```
385474
#[proc_macro_attribute]
386475
pub fn launch(args: TokenStream, input: TokenStream) -> TokenStream {
387476
emit!(attribute::entry::launch_attribute(args, input))

core/lib/src/lib.rs

+24-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,30 @@ pub fn custom<T: figment::Provider>(provider: T) -> Rocket<Build> {
179179

180180
/// Retrofits support for `async fn` in trait impls and declarations.
181181
///
182-
/// See [`async_trait`](mod@async_trait) for full details.
182+
/// Any trait declaration or trait `impl` decorated with `#[async_trait]` is
183+
/// retrofitted with support for `async fn`s:
184+
///
185+
/// ```rust
186+
/// # use rocket::*;
187+
/// #[async_trait]
188+
/// trait MyAsyncTrait {
189+
/// async fn do_async_work();
190+
/// }
191+
///
192+
/// #[async_trait]
193+
/// impl MyAsyncTrait for () {
194+
/// async fn do_async_work() { /* .. */ }
195+
/// }
196+
/// ```
197+
///
198+
/// All `impl`s for a trait declared with `#[async_trait]` must themselves be
199+
/// decorated with `#[async_trait]`. Many of Rocket's traits, such as
200+
/// [`FromRequest`](crate::request::FromRequest) and
201+
/// [`Fairing`](crate::fairing::Fairing) are `async`. As such, implementations
202+
/// of said traits must be decorated with `#[async_trait]`. See the individual
203+
/// trait docs for trait-specific details.
204+
///
205+
/// For more details on `#[async_trait]`, see [`async_trait`](mod@async_trait).
183206
#[doc(inline)]
184207
pub use async_trait::async_trait;
185208

core/lib/src/rocket.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ use crate::log::PaintExt;
5454
/// To launch an instance of `Rocket`, it _must_ progress through all three
5555
/// phases. To progress into the ignite or launch phases, a tokio `async`
5656
/// runtime is required. The [`#[main]`](crate::main) attribute initializes a
57-
/// Rocket-specific tokio runtime and runs attributed async code inside of it:
57+
/// Rocket-specific tokio runtime and runs the attributed `async fn` inside of
58+
/// it:
5859
///
5960
/// ```rust,no_run
6061
/// #[rocket::main]

0 commit comments

Comments
 (0)