tokio_macros/
lib.rs

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