2019-12-21 00:54:43 +03:00
|
|
|
#![allow(clippy::needless_doctest_main)]
|
2019-08-11 04:28:52 +09:00
|
|
|
#![warn(
|
|
|
|
|
missing_debug_implementations,
|
|
|
|
|
missing_docs,
|
|
|
|
|
rust_2018_idioms,
|
|
|
|
|
unreachable_pub
|
|
|
|
|
)]
|
2019-09-19 15:50:12 +09:00
|
|
|
#![doc(test(
|
|
|
|
|
no_crate_inject,
|
|
|
|
|
attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
|
|
|
|
|
))]
|
2019-05-14 10:27:36 -07:00
|
|
|
|
|
|
|
|
//! Macros for use with Tokio
|
2019-04-25 19:22:32 -07:00
|
|
|
|
2020-01-26 21:54:14 -08:00
|
|
|
// This `extern` is required for older `rustc` versions but newer `rustc`
|
|
|
|
|
// versions warn about the unused `extern crate`.
|
|
|
|
|
#[allow(unused_extern_crates)]
|
2019-04-25 19:22:32 -07:00
|
|
|
extern crate proc_macro;
|
|
|
|
|
|
2020-01-22 18:59:22 -08:00
|
|
|
mod entry;
|
|
|
|
|
mod select;
|
|
|
|
|
|
2019-04-25 19:22:32 -07:00
|
|
|
use proc_macro::TokenStream;
|
2019-10-02 13:58:34 -04:00
|
|
|
|
2020-12-23 09:26:14 -08:00
|
|
|
/// Marks async function to be executed by the selected runtime. This macro
|
|
|
|
|
/// helps set up a `Runtime` without requiring the user to use
|
2020-10-12 13:44:54 -04:00
|
|
|
/// [Runtime](../tokio/runtime/struct.Runtime.html) or
|
2020-09-05 21:22:47 +03:00
|
|
|
/// [Builder](../tokio/runtime/struct.Builder.html) directly.
|
|
|
|
|
///
|
2020-10-12 13:44:54 -04:00
|
|
|
/// Note: This macro is designed to be simplistic and targets applications that
|
|
|
|
|
/// do not require a complex setup. If the provided functionality is not
|
|
|
|
|
/// sufficient, you may be interested in using
|
|
|
|
|
/// [Builder](../tokio/runtime/struct.Builder.html), which provides a more
|
|
|
|
|
/// powerful interface.
|
2019-04-25 19:22:32 -07:00
|
|
|
///
|
2020-12-01 00:34:11 +08:00
|
|
|
/// Note: This macro can be used on any function and not just the `main`
|
2020-12-23 09:26:14 -08:00
|
|
|
/// function. Using it on a non-main function makes the function behave as if it
|
|
|
|
|
/// was synchronous by starting a new runtime each time it is called. If the
|
|
|
|
|
/// function is called often, it is preferable to create the runtime using the
|
|
|
|
|
/// runtime builder so the runtime can be reused across calls.
|
2020-12-01 00:34:11 +08:00
|
|
|
///
|
2020-10-12 13:44:54 -04:00
|
|
|
/// # Multi-threaded runtime
|
2019-06-27 20:40:22 +03:00
|
|
|
///
|
2020-10-12 13:44:54 -04:00
|
|
|
/// To use the multi-threaded runtime, the macro can be configured using
|
2020-02-26 10:38:54 -08:00
|
|
|
///
|
2020-10-12 13:44:54 -04:00
|
|
|
/// ```
|
|
|
|
|
/// #[tokio::main(flavor = "multi_thread", worker_threads = 10)]
|
|
|
|
|
/// # async fn main() {}
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
|
|
|
|
/// The `worker_threads` option configures the number of worker threads, and
|
|
|
|
|
/// defaults to the number of cpus on the system. This is the default flavor.
|
|
|
|
|
///
|
2020-12-23 09:26:14 -08:00
|
|
|
/// Note: The multi-threaded runtime requires the `rt-multi-thread` feature
|
|
|
|
|
/// flag.
|
2020-12-19 19:12:08 +01:00
|
|
|
///
|
2020-10-12 13:44:54 -04:00
|
|
|
/// # Current thread runtime
|
|
|
|
|
///
|
|
|
|
|
/// To use the single-threaded runtime known as the `current_thread` runtime,
|
|
|
|
|
/// the macro can be configured using
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// #[tokio::main(flavor = "current_thread")]
|
|
|
|
|
/// # async fn main() {}
|
|
|
|
|
/// ```
|
2019-06-27 20:40:22 +03:00
|
|
|
///
|
2019-09-24 16:03:26 +02:00
|
|
|
/// ## Function arguments:
|
|
|
|
|
///
|
|
|
|
|
/// Arguments are allowed for any functions aside from `main` which is special
|
|
|
|
|
///
|
2019-06-27 20:40:22 +03:00
|
|
|
/// ## Usage
|
2019-04-25 19:22:32 -07:00
|
|
|
///
|
2020-10-12 13:44:54 -04:00
|
|
|
/// ### Using the multi-thread runtime
|
2019-06-27 20:40:22 +03:00
|
|
|
///
|
|
|
|
|
/// ```rust
|
2019-11-16 07:19:45 -08:00
|
|
|
/// #[tokio::main]
|
2019-06-27 20:40:22 +03:00
|
|
|
/// async fn main() {
|
|
|
|
|
/// println!("Hello world");
|
|
|
|
|
/// }
|
2019-04-25 19:22:32 -07:00
|
|
|
/// ```
|
2019-11-16 07:19:45 -08:00
|
|
|
///
|
2020-07-24 16:32:15 +01:00
|
|
|
/// Equivalent code not using `#[tokio::main]`
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// fn main() {
|
2021-09-30 10:38:52 +02:00
|
|
|
/// tokio::runtime::Builder::new_multi_thread()
|
2020-07-24 16:32:15 +01:00
|
|
|
/// .enable_all()
|
|
|
|
|
/// .build()
|
2021-09-30 10:38:52 +02:00
|
|
|
/// .unwrap()
|
|
|
|
|
/// .block_on(async {
|
|
|
|
|
/// println!("Hello world");
|
|
|
|
|
/// })
|
2020-07-24 16:32:15 +01:00
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
2020-10-12 13:44:54 -04:00
|
|
|
/// ### Using current thread runtime
|
2020-07-26 18:51:56 +02:00
|
|
|
///
|
|
|
|
|
/// The basic scheduler is single-threaded.
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2020-10-12 13:44:54 -04:00
|
|
|
/// #[tokio::main(flavor = "current_thread")]
|
2020-07-26 18:51:56 +02:00
|
|
|
/// async fn main() {
|
|
|
|
|
/// println!("Hello world");
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
|
|
|
|
/// Equivalent code not using `#[tokio::main]`
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// fn main() {
|
2021-09-30 10:38:52 +02:00
|
|
|
/// tokio::runtime::Builder::new_current_thread()
|
2020-07-26 18:51:56 +02:00
|
|
|
/// .enable_all()
|
|
|
|
|
/// .build()
|
2021-09-30 10:38:52 +02:00
|
|
|
/// .unwrap()
|
|
|
|
|
/// .block_on(async {
|
|
|
|
|
/// println!("Hello world");
|
|
|
|
|
/// })
|
2020-07-26 18:51:56 +02:00
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
2020-10-12 13:44:54 -04:00
|
|
|
/// ### Set number of worker threads
|
2020-01-07 14:29:44 -08:00
|
|
|
///
|
|
|
|
|
/// ```rust
|
2020-10-12 13:44:54 -04:00
|
|
|
/// #[tokio::main(worker_threads = 2)]
|
2020-01-07 14:29:44 -08:00
|
|
|
/// async fn main() {
|
|
|
|
|
/// println!("Hello world");
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
2020-05-20 12:50:41 -07:00
|
|
|
///
|
2020-07-24 16:32:15 +01:00
|
|
|
/// Equivalent code not using `#[tokio::main]`
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// fn main() {
|
2021-09-30 10:38:52 +02:00
|
|
|
/// tokio::runtime::Builder::new_multi_thread()
|
2020-10-12 13:44:54 -04:00
|
|
|
/// .worker_threads(2)
|
2020-07-24 16:32:15 +01:00
|
|
|
/// .enable_all()
|
|
|
|
|
/// .build()
|
2021-09-30 10:38:52 +02:00
|
|
|
/// .unwrap()
|
|
|
|
|
/// .block_on(async {
|
|
|
|
|
/// println!("Hello world");
|
|
|
|
|
/// })
|
2020-07-24 16:32:15 +01:00
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
2021-02-05 14:12:25 -05:00
|
|
|
/// ### Configure the runtime to start with time paused
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// #[tokio::main(flavor = "current_thread", start_paused = true)]
|
|
|
|
|
/// async fn main() {
|
|
|
|
|
/// println!("Hello world");
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
|
|
|
|
/// Equivalent code not using `#[tokio::main]`
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// fn main() {
|
2021-09-30 10:38:52 +02:00
|
|
|
/// tokio::runtime::Builder::new_current_thread()
|
2021-02-05 14:12:25 -05:00
|
|
|
/// .enable_all()
|
|
|
|
|
/// .start_paused(true)
|
|
|
|
|
/// .build()
|
2021-09-30 10:38:52 +02:00
|
|
|
/// .unwrap()
|
|
|
|
|
/// .block_on(async {
|
|
|
|
|
/// println!("Hello world");
|
|
|
|
|
/// })
|
2021-02-05 14:12:25 -05:00
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
2021-04-05 22:40:42 +02:00
|
|
|
/// Note that `start_paused` requires the `test-util` feature to be enabled.
|
|
|
|
|
///
|
2022-04-18 17:24:27 +08:00
|
|
|
/// ### Rename package
|
2020-05-20 12:50:41 -07:00
|
|
|
///
|
2022-04-18 17:24:27 +08:00
|
|
|
/// ```rust
|
|
|
|
|
/// use tokio as tokio1;
|
|
|
|
|
///
|
|
|
|
|
/// #[tokio1::main(crate = "tokio1")]
|
|
|
|
|
/// async fn main() {
|
|
|
|
|
/// println!("Hello world");
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
|
|
|
|
/// Equivalent code not using `#[tokio::main]`
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use tokio as tokio1;
|
|
|
|
|
///
|
|
|
|
|
/// fn main() {
|
|
|
|
|
/// tokio1::runtime::Builder::new_multi_thread()
|
|
|
|
|
/// .enable_all()
|
|
|
|
|
/// .build()
|
|
|
|
|
/// .unwrap()
|
|
|
|
|
/// .block_on(async {
|
|
|
|
|
/// println!("Hello world");
|
|
|
|
|
/// })
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
2020-01-07 14:29:44 -08:00
|
|
|
#[proc_macro_attribute]
|
|
|
|
|
#[cfg(not(test))] // Work around for rust-lang/rust#62127
|
|
|
|
|
pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
|
2020-10-12 13:44:54 -04:00
|
|
|
entry::main(args, item, true)
|
2019-12-27 21:56:43 +03:00
|
|
|
}
|
|
|
|
|
|
2020-07-24 16:32:15 +01:00
|
|
|
/// Marks async function to be executed by selected runtime. This macro helps set up a `Runtime`
|
|
|
|
|
/// without requiring the user to use [Runtime](../tokio/runtime/struct.Runtime.html) or
|
|
|
|
|
/// [Builder](../tokio/runtime/struct.builder.html) directly.
|
2019-12-27 21:56:43 +03:00
|
|
|
///
|
|
|
|
|
/// ## Function arguments:
|
|
|
|
|
///
|
|
|
|
|
/// Arguments are allowed for any functions aside from `main` which is special
|
|
|
|
|
///
|
|
|
|
|
/// ## Usage
|
|
|
|
|
///
|
|
|
|
|
/// ### Using default
|
2019-06-27 20:40:22 +03:00
|
|
|
///
|
|
|
|
|
/// ```rust
|
2020-10-12 13:44:54 -04:00
|
|
|
/// #[tokio::main(flavor = "current_thread")]
|
2019-04-25 19:22:32 -07:00
|
|
|
/// async fn main() {
|
2019-06-27 20:40:22 +03:00
|
|
|
/// println!("Hello world");
|
2019-04-25 19:22:32 -07:00
|
|
|
/// }
|
2019-06-25 20:14:21 -07:00
|
|
|
/// ```
|
2020-05-20 12:50:41 -07:00
|
|
|
///
|
2020-07-24 16:32:15 +01:00
|
|
|
/// Equivalent code not using `#[tokio::main]`
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// fn main() {
|
2021-09-30 10:38:52 +02:00
|
|
|
/// tokio::runtime::Builder::new_current_thread()
|
2020-07-24 16:32:15 +01:00
|
|
|
/// .enable_all()
|
|
|
|
|
/// .build()
|
2021-09-30 10:38:52 +02:00
|
|
|
/// .unwrap()
|
|
|
|
|
/// .block_on(async {
|
|
|
|
|
/// println!("Hello world");
|
|
|
|
|
/// })
|
2020-07-24 16:32:15 +01:00
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
2022-04-18 17:24:27 +08:00
|
|
|
/// ### Rename package
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use tokio as tokio1;
|
|
|
|
|
///
|
|
|
|
|
/// #[tokio1::main(crate = "tokio1")]
|
|
|
|
|
/// async fn main() {
|
|
|
|
|
/// println!("Hello world");
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
|
|
|
|
/// Equivalent code not using `#[tokio::main]`
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use tokio as tokio1;
|
2020-05-20 12:50:41 -07:00
|
|
|
///
|
2022-04-18 17:24:27 +08:00
|
|
|
/// fn main() {
|
|
|
|
|
/// tokio1::runtime::Builder::new_multi_thread()
|
|
|
|
|
/// .enable_all()
|
|
|
|
|
/// .build()
|
|
|
|
|
/// .unwrap()
|
|
|
|
|
/// .block_on(async {
|
|
|
|
|
/// println!("Hello world");
|
|
|
|
|
/// })
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
2019-04-25 19:22:32 -07:00
|
|
|
#[proc_macro_attribute]
|
2019-06-25 20:14:21 -07:00
|
|
|
#[cfg(not(test))] // Work around for rust-lang/rust#62127
|
2020-10-13 06:13:23 +09:00
|
|
|
pub fn main_rt(args: TokenStream, item: TokenStream) -> TokenStream {
|
2020-01-21 10:46:32 -08:00
|
|
|
entry::main(args, item, false)
|
2019-04-25 19:22:32 -07:00
|
|
|
}
|
|
|
|
|
|
2020-02-11 16:09:40 -05:00
|
|
|
/// Marks async function to be executed by runtime, suitable to test environment
|
2020-01-07 14:29:44 -08:00
|
|
|
///
|
|
|
|
|
/// ## Usage
|
|
|
|
|
///
|
2020-10-12 13:44:54 -04:00
|
|
|
/// ### Multi-thread runtime
|
2020-01-07 14:29:44 -08:00
|
|
|
///
|
|
|
|
|
/// ```no_run
|
2020-10-12 13:44:54 -04:00
|
|
|
/// #[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
2020-01-07 14:29:44 -08:00
|
|
|
/// async fn my_test() {
|
|
|
|
|
/// assert!(true);
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
|
|
|
|
/// ### Using default
|
|
|
|
|
///
|
2020-11-26 13:46:15 -05:00
|
|
|
/// The default test runtime is single-threaded.
|
2020-10-12 13:44:54 -04:00
|
|
|
///
|
2020-01-07 14:29:44 -08:00
|
|
|
/// ```no_run
|
|
|
|
|
/// #[tokio::test]
|
|
|
|
|
/// async fn my_test() {
|
|
|
|
|
/// assert!(true);
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
2020-05-20 12:50:41 -07:00
|
|
|
///
|
2021-02-05 14:12:25 -05:00
|
|
|
/// ### Configure the runtime to start with time paused
|
|
|
|
|
///
|
|
|
|
|
/// ```no_run
|
|
|
|
|
/// #[tokio::test(start_paused = true)]
|
|
|
|
|
/// async fn my_test() {
|
|
|
|
|
/// assert!(true);
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
2021-04-05 22:40:42 +02:00
|
|
|
/// Note that `start_paused` requires the `test-util` feature to be enabled.
|
|
|
|
|
///
|
2022-04-18 17:24:27 +08:00
|
|
|
/// ### Rename package
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use tokio as tokio1;
|
2020-05-20 12:50:41 -07:00
|
|
|
///
|
2022-04-18 17:24:27 +08:00
|
|
|
/// #[tokio1::test(crate = "tokio1")]
|
|
|
|
|
/// async fn my_test() {
|
|
|
|
|
/// println!("Hello world");
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
2020-01-07 14:29:44 -08:00
|
|
|
#[proc_macro_attribute]
|
2020-10-12 13:44:54 -04:00
|
|
|
pub fn test(args: TokenStream, item: TokenStream) -> TokenStream {
|
2020-01-21 10:46:32 -08:00
|
|
|
entry::test(args, item, true)
|
2020-01-07 14:29:44 -08:00
|
|
|
}
|
|
|
|
|
|
2020-02-11 16:09:40 -05:00
|
|
|
/// Marks async function to be executed by runtime, suitable to test environment
|
2019-06-27 20:40:22 +03:00
|
|
|
///
|
2019-10-02 13:58:34 -04:00
|
|
|
/// ## Usage
|
|
|
|
|
///
|
2019-08-09 17:04:41 +02:00
|
|
|
/// ```no_run
|
2019-04-25 19:22:32 -07:00
|
|
|
/// #[tokio::test]
|
|
|
|
|
/// async fn my_test() {
|
|
|
|
|
/// assert!(true);
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[proc_macro_attribute]
|
2020-10-13 06:13:23 +09:00
|
|
|
pub fn test_rt(args: TokenStream, item: TokenStream) -> TokenStream {
|
2020-10-12 13:44:54 -04:00
|
|
|
entry::test(args, item, false)
|
2019-12-27 21:56:43 +03:00
|
|
|
}
|
|
|
|
|
|
2020-10-12 13:44:54 -04:00
|
|
|
/// Always fails with the error message below.
|
|
|
|
|
/// ```text
|
2020-10-13 06:13:23 +09:00
|
|
|
/// The #[tokio::main] macro requires rt or rt-multi-thread.
|
2019-12-27 21:56:43 +03:00
|
|
|
/// ```
|
|
|
|
|
#[proc_macro_attribute]
|
2020-10-12 13:44:54 -04:00
|
|
|
pub fn main_fail(_args: TokenStream, _item: TokenStream) -> TokenStream {
|
|
|
|
|
syn::Error::new(
|
|
|
|
|
proc_macro2::Span::call_site(),
|
2020-10-13 06:13:23 +09:00
|
|
|
"The #[tokio::main] macro requires rt or rt-multi-thread.",
|
2020-10-12 13:44:54 -04:00
|
|
|
)
|
|
|
|
|
.to_compile_error()
|
|
|
|
|
.into()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Always fails with the error message below.
|
|
|
|
|
/// ```text
|
2020-10-13 06:13:23 +09:00
|
|
|
/// The #[tokio::test] macro requires rt or rt-multi-thread.
|
2020-10-12 13:44:54 -04:00
|
|
|
/// ```
|
|
|
|
|
#[proc_macro_attribute]
|
|
|
|
|
pub fn test_fail(_args: TokenStream, _item: TokenStream) -> TokenStream {
|
|
|
|
|
syn::Error::new(
|
|
|
|
|
proc_macro2::Span::call_site(),
|
2020-10-13 06:13:23 +09:00
|
|
|
"The #[tokio::test] macro requires rt or rt-multi-thread.",
|
2020-10-12 13:44:54 -04:00
|
|
|
)
|
|
|
|
|
.to_compile_error()
|
|
|
|
|
.into()
|
2020-01-07 14:29:44 -08:00
|
|
|
}
|
2020-01-22 18:59:22 -08:00
|
|
|
|
|
|
|
|
/// Implementation detail of the `select!` macro. This macro is **not** intended
|
|
|
|
|
/// to be used as part of the public API and is permitted to change.
|
|
|
|
|
#[proc_macro]
|
|
|
|
|
#[doc(hidden)]
|
|
|
|
|
pub fn select_priv_declare_output_enum(input: TokenStream) -> TokenStream {
|
|
|
|
|
select::declare_output_enum(input)
|
|
|
|
|
}
|
2021-11-02 18:05:24 +01:00
|
|
|
|
|
|
|
|
/// Implementation detail of the `select!` macro. This macro is **not** intended
|
|
|
|
|
/// to be used as part of the public API and is permitted to change.
|
|
|
|
|
#[proc_macro]
|
|
|
|
|
#[doc(hidden)]
|
|
|
|
|
pub fn select_priv_clean_pattern(input: TokenStream) -> TokenStream {
|
|
|
|
|
select::clean_pattern_macro(input)
|
|
|
|
|
}
|