tokio_macros/
lib.rs

1#![allow(unknown_lints, unexpected_cfgs)]
2#![allow(clippy::needless_doctest_main)]
3#![warn(
4    missing_debug_implementations,
5    missing_docs,
6    rust_2018_idioms,
7    unreachable_pub
8)]
9#![doc(test(
10    no_crate_inject,
11    attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
12))]
13
14//! Macros for use with Tokio
15
16// This `extern` is required for older `rustc` versions but newer `rustc`
17// versions warn about the unused `extern crate`.
18#[allow(unused_extern_crates)]
19extern crate proc_macro;
20
21mod entry;
22mod select;
23
24use proc_macro::TokenStream;
25
26/// Marks async function to be executed by the selected runtime. This macro
27/// helps set up a `Runtime` without requiring the user to use
28/// [Runtime](../tokio/runtime/struct.Runtime.html) or
29/// [Builder](../tokio/runtime/struct.Builder.html) directly.
30///
31/// Note: This macro is designed to be simplistic and targets applications that
32/// do not require a complex setup. If the provided functionality is not
33/// sufficient, you may be interested in using
34/// [Builder](../tokio/runtime/struct.Builder.html), which provides a more
35/// powerful interface.
36///
37/// Note: This macro can be used on any function and not just the `main`
38/// function. Using it on a non-main function makes the function behave as if it
39/// was synchronous by starting a new runtime each time it is called. If the
40/// function is called often, it is preferable to create the runtime using the
41/// runtime builder so the runtime can be reused across calls.
42///
43/// # Non-worker async function
44///
45/// Note that the async function marked with this macro does not run as a
46/// worker. The expectation is that other tasks are spawned by the function here.
47/// Awaiting on other futures from the function provided here will not
48/// perform as fast as those spawned as workers.
49///
50/// # Multi-threaded runtime
51///
52/// To use the multi-threaded runtime, the macro can be configured using
53///
54/// ```
55/// #[tokio::main(flavor = "multi_thread", worker_threads = 10)]
56/// # async fn main() {}
57/// ```
58///
59/// The `worker_threads` option configures the number of worker threads, and
60/// defaults to the number of cpus on the system. This is the default flavor.
61///
62/// Note: The multi-threaded runtime requires the `rt-multi-thread` feature
63/// flag.
64///
65/// # Current thread runtime
66///
67/// To use the single-threaded runtime known as the `current_thread` runtime,
68/// the macro can be configured using
69///
70/// ```
71/// #[tokio::main(flavor = "current_thread")]
72/// # async fn main() {}
73/// ```
74///
75/// ## Function arguments:
76///
77/// Arguments are allowed for any functions aside from `main` which is special
78///
79/// ## Usage
80///
81/// ### Using the multi-thread runtime
82///
83/// ```rust
84/// #[tokio::main]
85/// async fn main() {
86///     println!("Hello world");
87/// }
88/// ```
89///
90/// Equivalent code not using `#[tokio::main]`
91///
92/// ```rust
93/// fn main() {
94///     tokio::runtime::Builder::new_multi_thread()
95///         .enable_all()
96///         .build()
97///         .unwrap()
98///         .block_on(async {
99///             println!("Hello world");
100///         })
101/// }
102/// ```
103///
104/// ### Using current thread runtime
105///
106/// The basic scheduler is single-threaded.
107///
108/// ```rust
109/// #[tokio::main(flavor = "current_thread")]
110/// async fn main() {
111///     println!("Hello world");
112/// }
113/// ```
114///
115/// Equivalent code not using `#[tokio::main]`
116///
117/// ```rust
118/// fn main() {
119///     tokio::runtime::Builder::new_current_thread()
120///         .enable_all()
121///         .build()
122///         .unwrap()
123///         .block_on(async {
124///             println!("Hello world");
125///         })
126/// }
127/// ```
128///
129/// ### Set number of worker threads
130///
131/// ```rust
132/// #[tokio::main(worker_threads = 2)]
133/// async fn main() {
134///     println!("Hello world");
135/// }
136/// ```
137///
138/// Equivalent code not using `#[tokio::main]`
139///
140/// ```rust
141/// fn main() {
142///     tokio::runtime::Builder::new_multi_thread()
143///         .worker_threads(2)
144///         .enable_all()
145///         .build()
146///         .unwrap()
147///         .block_on(async {
148///             println!("Hello world");
149///         })
150/// }
151/// ```
152///
153/// ### Configure the runtime to start with time paused
154///
155/// ```rust
156/// #[tokio::main(flavor = "current_thread", start_paused = true)]
157/// async fn main() {
158///     println!("Hello world");
159/// }
160/// ```
161///
162/// Equivalent code not using `#[tokio::main]`
163///
164/// ```rust
165/// fn main() {
166///     tokio::runtime::Builder::new_current_thread()
167///         .enable_all()
168///         .start_paused(true)
169///         .build()
170///         .unwrap()
171///         .block_on(async {
172///             println!("Hello world");
173///         })
174/// }
175/// ```
176///
177/// Note that `start_paused` requires the `test-util` feature to be enabled.
178///
179/// ### Rename package
180///
181/// ```rust
182/// use tokio as tokio1;
183///
184/// #[tokio1::main(crate = "tokio1")]
185/// async fn main() {
186///     println!("Hello world");
187/// }
188/// ```
189///
190/// Equivalent code not using `#[tokio::main]`
191///
192/// ```rust
193/// use tokio as tokio1;
194///
195/// fn main() {
196///     tokio1::runtime::Builder::new_multi_thread()
197///         .enable_all()
198///         .build()
199///         .unwrap()
200///         .block_on(async {
201///             println!("Hello world");
202///         })
203/// }
204/// ```
205///
206/// ### Configure unhandled panic behavior
207///
208/// Available options are `shutdown_runtime` and `ignore`. For more details, see
209/// [`Builder::unhandled_panic`].
210///
211/// This option is only compatible with the `current_thread` runtime.
212///
213/// ```no_run
214/// #[cfg(tokio_unstable)]
215/// #[tokio::main(flavor = "current_thread", unhandled_panic = "shutdown_runtime")]
216/// async fn main() {
217///     let _ = tokio::spawn(async {
218///         panic!("This panic will shutdown the runtime.");
219///     }).await;
220/// }
221/// # #[cfg(not(tokio_unstable))]
222/// # fn main() { }
223/// ```
224///
225/// Equivalent code not using `#[tokio::main]`
226///
227/// ```no_run
228/// #[cfg(tokio_unstable)]
229/// fn main() {
230///     tokio::runtime::Builder::new_current_thread()
231///         .enable_all()
232///         .unhandled_panic(UnhandledPanic::ShutdownRuntime)
233///         .build()
234///         .unwrap()
235///         .block_on(async {
236///             let _ = tokio::spawn(async {
237///                 panic!("This panic will shutdown the runtime.");
238///             }).await;
239///         })
240/// }
241/// # #[cfg(not(tokio_unstable))]
242/// # fn main() { }
243/// ```
244///
245/// **Note**: This option depends on Tokio's [unstable API][unstable]. See [the
246/// documentation on unstable features][unstable] for details on how to enable
247/// Tokio's unstable features.
248///
249/// [`Builder::unhandled_panic`]: ../tokio/runtime/struct.Builder.html#method.unhandled_panic
250/// [unstable]: ../tokio/index.html#unstable-features
251#[proc_macro_attribute]
252pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
253    entry::main(args.into(), item.into(), true).into()
254}
255
256/// Marks async function to be executed by selected runtime. This macro helps set up a `Runtime`
257/// without requiring the user to use [Runtime](../tokio/runtime/struct.Runtime.html) or
258/// [Builder](../tokio/runtime/struct.Builder.html) directly.
259///
260/// ## Function arguments:
261///
262/// Arguments are allowed for any functions aside from `main` which is special
263///
264/// ## Usage
265///
266/// ### Using default
267///
268/// ```rust
269/// #[tokio::main(flavor = "current_thread")]
270/// async fn main() {
271///     println!("Hello world");
272/// }
273/// ```
274///
275/// Equivalent code not using `#[tokio::main]`
276///
277/// ```rust
278/// fn main() {
279///     tokio::runtime::Builder::new_current_thread()
280///         .enable_all()
281///         .build()
282///         .unwrap()
283///         .block_on(async {
284///             println!("Hello world");
285///         })
286/// }
287/// ```
288///
289/// ### Rename package
290///
291/// ```rust
292/// use tokio as tokio1;
293///
294/// #[tokio1::main(crate = "tokio1")]
295/// async fn main() {
296///     println!("Hello world");
297/// }
298/// ```
299///
300/// Equivalent code not using `#[tokio::main]`
301///
302/// ```rust
303/// use tokio as tokio1;
304///
305/// fn main() {
306///     tokio1::runtime::Builder::new_multi_thread()
307///         .enable_all()
308///         .build()
309///         .unwrap()
310///         .block_on(async {
311///             println!("Hello world");
312///         })
313/// }
314/// ```
315#[proc_macro_attribute]
316pub fn main_rt(args: TokenStream, item: TokenStream) -> TokenStream {
317    entry::main(args.into(), item.into(), false).into()
318}
319
320/// Marks async function to be executed by runtime, suitable to test environment.
321/// This macro helps set up a `Runtime` without requiring the user to use
322/// [Runtime](../tokio/runtime/struct.Runtime.html) or
323/// [Builder](../tokio/runtime/struct.Builder.html) directly.
324///
325/// Note: This macro is designed to be simplistic and targets applications that
326/// do not require a complex setup. If the provided functionality is not
327/// sufficient, you may be interested in using
328/// [Builder](../tokio/runtime/struct.Builder.html), which provides a more
329/// powerful interface.
330///
331/// # Multi-threaded runtime
332///
333/// To use the multi-threaded runtime, the macro can be configured using
334///
335/// ```no_run
336/// #[tokio::test(flavor = "multi_thread", worker_threads = 1)]
337/// async fn my_test() {
338///     assert!(true);
339/// }
340/// ```
341///
342/// The `worker_threads` option configures the number of worker threads, and
343/// defaults to the number of cpus on the system.
344///
345/// Note: The multi-threaded runtime requires the `rt-multi-thread` feature
346/// flag.
347///
348/// # Current thread runtime
349///
350/// The default test runtime is single-threaded. Each test gets a
351/// separate current-thread runtime.
352///
353/// ```no_run
354/// #[tokio::test]
355/// async fn my_test() {
356///     assert!(true);
357/// }
358/// ```
359///
360/// ## Usage
361///
362/// ### Using the multi-thread runtime
363///
364/// ```no_run
365/// #[tokio::test(flavor = "multi_thread")]
366/// async fn my_test() {
367///     assert!(true);
368/// }
369/// ```
370///
371/// Equivalent code not using `#[tokio::test]`
372///
373/// ```no_run
374/// #[test]
375/// fn my_test() {
376///     tokio::runtime::Builder::new_multi_thread()
377///         .enable_all()
378///         .build()
379///         .unwrap()
380///         .block_on(async {
381///             assert!(true);
382///         })
383/// }
384/// ```
385///
386/// ### Using current thread runtime
387///
388/// ```no_run
389/// #[tokio::test]
390/// async fn my_test() {
391///     assert!(true);
392/// }
393/// ```
394///
395/// Equivalent code not using `#[tokio::test]`
396///
397/// ```no_run
398/// #[test]
399/// fn my_test() {
400///     tokio::runtime::Builder::new_current_thread()
401///         .enable_all()
402///         .build()
403///         .unwrap()
404///         .block_on(async {
405///             assert!(true);
406///         })
407/// }
408/// ```
409///
410/// ### Set number of worker threads
411///
412/// ```no_run
413/// #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
414/// async fn my_test() {
415///     assert!(true);
416/// }
417/// ```
418///
419/// Equivalent code not using `#[tokio::test]`
420///
421/// ```no_run
422/// #[test]
423/// fn my_test() {
424///     tokio::runtime::Builder::new_multi_thread()
425///         .worker_threads(2)
426///         .enable_all()
427///         .build()
428///         .unwrap()
429///         .block_on(async {
430///             assert!(true);
431///         })
432/// }
433/// ```
434///
435/// ### Configure the runtime to start with time paused
436///
437/// ```no_run
438/// #[tokio::test(start_paused = true)]
439/// async fn my_test() {
440///     assert!(true);
441/// }
442/// ```
443///
444/// Equivalent code not using `#[tokio::test]`
445///
446/// ```no_run
447/// #[test]
448/// fn my_test() {
449///     tokio::runtime::Builder::new_current_thread()
450///         .enable_all()
451///         .start_paused(true)
452///         .build()
453///         .unwrap()
454///         .block_on(async {
455///             assert!(true);
456///         })
457/// }
458/// ```
459///
460/// Note that `start_paused` requires the `test-util` feature to be enabled.
461///
462/// ### Rename package
463///
464/// ```rust
465/// use tokio as tokio1;
466///
467/// #[tokio1::test(crate = "tokio1")]
468/// async fn my_test() {
469///     println!("Hello world");
470/// }
471/// ```
472///
473/// ### Configure unhandled panic behavior
474///
475/// Available options are `shutdown_runtime` and `ignore`. For more details, see
476/// [`Builder::unhandled_panic`].
477///
478/// This option is only compatible with the `current_thread` runtime.
479///
480/// ```no_run
481/// #[cfg(tokio_unstable)]
482/// #[tokio::test(flavor = "current_thread", unhandled_panic = "shutdown_runtime")]
483/// async fn my_test() {
484///     let _ = tokio::spawn(async {
485///         panic!("This panic will shutdown the runtime.");
486///     }).await;
487/// }
488/// # #[cfg(not(tokio_unstable))]
489/// # fn main() { }
490/// ```
491///
492/// Equivalent code not using `#[tokio::test]`
493///
494/// ```no_run
495/// #[cfg(tokio_unstable)]
496/// #[test]
497/// fn my_test() {
498///     tokio::runtime::Builder::new_current_thread()
499///         .enable_all()
500///         .unhandled_panic(UnhandledPanic::ShutdownRuntime)
501///         .build()
502///         .unwrap()
503///         .block_on(async {
504///             let _ = tokio::spawn(async {
505///                 panic!("This panic will shutdown the runtime.");
506///             }).await;
507///         })
508/// }
509/// # #[cfg(not(tokio_unstable))]
510/// # fn main() { }
511/// ```
512///
513/// **Note**: This option depends on Tokio's [unstable API][unstable]. See [the
514/// documentation on unstable features][unstable] for details on how to enable
515/// Tokio's unstable features.
516///
517/// [`Builder::unhandled_panic`]: ../tokio/runtime/struct.Builder.html#method.unhandled_panic
518/// [unstable]: ../tokio/index.html#unstable-features
519#[proc_macro_attribute]
520pub fn test(args: TokenStream, item: TokenStream) -> TokenStream {
521    entry::test(args.into(), item.into(), true).into()
522}
523
524/// Marks async function to be executed by runtime, suitable to test environment
525///
526/// ## Usage
527///
528/// ```no_run
529/// #[tokio::test]
530/// async fn my_test() {
531///     assert!(true);
532/// }
533/// ```
534#[proc_macro_attribute]
535pub fn test_rt(args: TokenStream, item: TokenStream) -> TokenStream {
536    entry::test(args.into(), item.into(), false).into()
537}
538
539/// Always fails with the error message below.
540/// ```text
541/// The #[tokio::main] macro requires rt or rt-multi-thread.
542/// ```
543#[proc_macro_attribute]
544pub fn main_fail(_args: TokenStream, _item: TokenStream) -> TokenStream {
545    syn::Error::new(
546        proc_macro2::Span::call_site(),
547        "The #[tokio::main] macro requires rt or rt-multi-thread.",
548    )
549    .to_compile_error()
550    .into()
551}
552
553/// Always fails with the error message below.
554/// ```text
555/// The #[tokio::test] macro requires rt or rt-multi-thread.
556/// ```
557#[proc_macro_attribute]
558pub fn test_fail(_args: TokenStream, _item: TokenStream) -> TokenStream {
559    syn::Error::new(
560        proc_macro2::Span::call_site(),
561        "The #[tokio::test] macro requires rt or rt-multi-thread.",
562    )
563    .to_compile_error()
564    .into()
565}
566
567/// Implementation detail of the `select!` macro. This macro is **not** intended
568/// to be used as part of the public API and is permitted to change.
569#[proc_macro]
570#[doc(hidden)]
571pub fn select_priv_declare_output_enum(input: TokenStream) -> TokenStream {
572    select::declare_output_enum(input)
573}
574
575/// Implementation detail of the `select!` macro. This macro is **not** intended
576/// to be used as part of the public API and is permitted to change.
577#[proc_macro]
578#[doc(hidden)]
579pub fn select_priv_clean_pattern(input: TokenStream) -> TokenStream {
580    select::clean_pattern_macro(input)
581}