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/// # #![allow(unknown_lints, unexpected_cfgs)]
215/// #[cfg(tokio_unstable)]
216/// #[tokio::main(flavor = "current_thread", unhandled_panic = "shutdown_runtime")]
217/// async fn main() {
218/// let _ = tokio::spawn(async {
219/// panic!("This panic will shutdown the runtime.");
220/// }).await;
221/// }
222/// # #[cfg(not(tokio_unstable))]
223/// # fn main() { }
224/// ```
225///
226/// Equivalent code not using `#[tokio::main]`
227///
228/// ```no_run
229/// # #![allow(unknown_lints, unexpected_cfgs)]
230/// #[cfg(tokio_unstable)]
231/// fn main() {
232/// tokio::runtime::Builder::new_current_thread()
233/// .enable_all()
234/// .unhandled_panic(UnhandledPanic::ShutdownRuntime)
235/// .build()
236/// .unwrap()
237/// .block_on(async {
238/// let _ = tokio::spawn(async {
239/// panic!("This panic will shutdown the runtime.");
240/// }).await;
241/// })
242/// }
243/// # #[cfg(not(tokio_unstable))]
244/// # fn main() { }
245/// ```
246///
247/// **Note**: This option depends on Tokio's [unstable API][unstable]. See [the
248/// documentation on unstable features][unstable] for details on how to enable
249/// Tokio's unstable features.
250///
251/// [`Builder::unhandled_panic`]: ../tokio/runtime/struct.Builder.html#method.unhandled_panic
252/// [unstable]: ../tokio/index.html#unstable-features
253#[proc_macro_attribute]
254pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
255 entry::main(args.into(), item.into(), true).into()
256}
257
258/// Marks async function to be executed by selected runtime. This macro helps set up a `Runtime`
259/// without requiring the user to use [Runtime](../tokio/runtime/struct.Runtime.html) or
260/// [Builder](../tokio/runtime/struct.Builder.html) directly.
261///
262/// ## Function arguments:
263///
264/// Arguments are allowed for any functions aside from `main` which is special
265///
266/// ## Usage
267///
268/// ### Using default
269///
270/// ```rust
271/// #[tokio::main(flavor = "current_thread")]
272/// async fn main() {
273/// println!("Hello world");
274/// }
275/// ```
276///
277/// Equivalent code not using `#[tokio::main]`
278///
279/// ```rust
280/// fn main() {
281/// tokio::runtime::Builder::new_current_thread()
282/// .enable_all()
283/// .build()
284/// .unwrap()
285/// .block_on(async {
286/// println!("Hello world");
287/// })
288/// }
289/// ```
290///
291/// ### Rename package
292///
293/// ```rust
294/// use tokio as tokio1;
295///
296/// #[tokio1::main(crate = "tokio1")]
297/// async fn main() {
298/// println!("Hello world");
299/// }
300/// ```
301///
302/// Equivalent code not using `#[tokio::main]`
303///
304/// ```rust
305/// use tokio as tokio1;
306///
307/// fn main() {
308/// tokio1::runtime::Builder::new_multi_thread()
309/// .enable_all()
310/// .build()
311/// .unwrap()
312/// .block_on(async {
313/// println!("Hello world");
314/// })
315/// }
316/// ```
317#[proc_macro_attribute]
318pub fn main_rt(args: TokenStream, item: TokenStream) -> TokenStream {
319 entry::main(args.into(), item.into(), false).into()
320}
321
322/// Marks async function to be executed by runtime, suitable to test environment.
323/// This macro helps set up a `Runtime` without requiring the user to use
324/// [Runtime](../tokio/runtime/struct.Runtime.html) or
325/// [Builder](../tokio/runtime/struct.Builder.html) directly.
326///
327/// Note: This macro is designed to be simplistic and targets applications that
328/// do not require a complex setup. If the provided functionality is not
329/// sufficient, you may be interested in using
330/// [Builder](../tokio/runtime/struct.Builder.html), which provides a more
331/// powerful interface.
332///
333/// # Multi-threaded runtime
334///
335/// To use the multi-threaded runtime, the macro can be configured using
336///
337/// ```no_run
338/// #[tokio::test(flavor = "multi_thread", worker_threads = 1)]
339/// async fn my_test() {
340/// assert!(true);
341/// }
342/// ```
343///
344/// The `worker_threads` option configures the number of worker threads, and
345/// defaults to the number of cpus on the system.
346///
347/// Note: The multi-threaded runtime requires the `rt-multi-thread` feature
348/// flag.
349///
350/// # Current thread runtime
351///
352/// The default test runtime is single-threaded. Each test gets a
353/// separate current-thread runtime.
354///
355/// ```no_run
356/// #[tokio::test]
357/// async fn my_test() {
358/// assert!(true);
359/// }
360/// ```
361///
362/// ## Usage
363///
364/// ### Using the multi-thread runtime
365///
366/// ```no_run
367/// #[tokio::test(flavor = "multi_thread")]
368/// async fn my_test() {
369/// assert!(true);
370/// }
371/// ```
372///
373/// Equivalent code not using `#[tokio::test]`
374///
375/// ```no_run
376/// #[test]
377/// fn my_test() {
378/// tokio::runtime::Builder::new_multi_thread()
379/// .enable_all()
380/// .build()
381/// .unwrap()
382/// .block_on(async {
383/// assert!(true);
384/// })
385/// }
386/// ```
387///
388/// ### Using current thread runtime
389///
390/// ```no_run
391/// #[tokio::test]
392/// async fn my_test() {
393/// assert!(true);
394/// }
395/// ```
396///
397/// Equivalent code not using `#[tokio::test]`
398///
399/// ```no_run
400/// #[test]
401/// fn my_test() {
402/// tokio::runtime::Builder::new_current_thread()
403/// .enable_all()
404/// .build()
405/// .unwrap()
406/// .block_on(async {
407/// assert!(true);
408/// })
409/// }
410/// ```
411///
412/// ### Set number of worker threads
413///
414/// ```no_run
415/// #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
416/// async fn my_test() {
417/// assert!(true);
418/// }
419/// ```
420///
421/// Equivalent code not using `#[tokio::test]`
422///
423/// ```no_run
424/// #[test]
425/// fn my_test() {
426/// tokio::runtime::Builder::new_multi_thread()
427/// .worker_threads(2)
428/// .enable_all()
429/// .build()
430/// .unwrap()
431/// .block_on(async {
432/// assert!(true);
433/// })
434/// }
435/// ```
436///
437/// ### Configure the runtime to start with time paused
438///
439/// ```no_run
440/// #[tokio::test(start_paused = true)]
441/// async fn my_test() {
442/// assert!(true);
443/// }
444/// ```
445///
446/// Equivalent code not using `#[tokio::test]`
447///
448/// ```no_run
449/// #[test]
450/// fn my_test() {
451/// tokio::runtime::Builder::new_current_thread()
452/// .enable_all()
453/// .start_paused(true)
454/// .build()
455/// .unwrap()
456/// .block_on(async {
457/// assert!(true);
458/// })
459/// }
460/// ```
461///
462/// Note that `start_paused` requires the `test-util` feature to be enabled.
463///
464/// ### Rename package
465///
466/// ```rust
467/// use tokio as tokio1;
468///
469/// #[tokio1::test(crate = "tokio1")]
470/// async fn my_test() {
471/// println!("Hello world");
472/// }
473/// ```
474///
475/// ### Configure unhandled panic behavior
476///
477/// Available options are `shutdown_runtime` and `ignore`. For more details, see
478/// [`Builder::unhandled_panic`].
479///
480/// This option is only compatible with the `current_thread` runtime.
481///
482/// ```no_run
483/// # #![allow(unknown_lints, unexpected_cfgs)]
484/// #[cfg(tokio_unstable)]
485/// #[tokio::test(flavor = "current_thread", unhandled_panic = "shutdown_runtime")]
486/// async fn my_test() {
487/// let _ = tokio::spawn(async {
488/// panic!("This panic will shutdown the runtime.");
489/// }).await;
490/// }
491/// # #[cfg(not(tokio_unstable))]
492/// # fn main() { }
493/// ```
494///
495/// Equivalent code not using `#[tokio::test]`
496///
497/// ```no_run
498/// # #![allow(unknown_lints, unexpected_cfgs)]
499/// #[cfg(tokio_unstable)]
500/// #[test]
501/// fn my_test() {
502/// tokio::runtime::Builder::new_current_thread()
503/// .enable_all()
504/// .unhandled_panic(UnhandledPanic::ShutdownRuntime)
505/// .build()
506/// .unwrap()
507/// .block_on(async {
508/// let _ = tokio::spawn(async {
509/// panic!("This panic will shutdown the runtime.");
510/// }).await;
511/// })
512/// }
513/// # #[cfg(not(tokio_unstable))]
514/// # fn main() { }
515/// ```
516///
517/// **Note**: This option depends on Tokio's [unstable API][unstable]. See [the
518/// documentation on unstable features][unstable] for details on how to enable
519/// Tokio's unstable features.
520///
521/// [`Builder::unhandled_panic`]: ../tokio/runtime/struct.Builder.html#method.unhandled_panic
522/// [unstable]: ../tokio/index.html#unstable-features
523#[proc_macro_attribute]
524pub fn test(args: TokenStream, item: TokenStream) -> TokenStream {
525 entry::test(args.into(), item.into(), true).into()
526}
527
528/// Marks async function to be executed by runtime, suitable to test environment
529///
530/// ## Usage
531///
532/// ```no_run
533/// #[tokio::test]
534/// async fn my_test() {
535/// assert!(true);
536/// }
537/// ```
538#[proc_macro_attribute]
539pub fn test_rt(args: TokenStream, item: TokenStream) -> TokenStream {
540 entry::test(args.into(), item.into(), false).into()
541}
542
543/// Always fails with the error message below.
544/// ```text
545/// The #[tokio::main] macro requires rt or rt-multi-thread.
546/// ```
547#[proc_macro_attribute]
548pub fn main_fail(_args: TokenStream, _item: TokenStream) -> TokenStream {
549 syn::Error::new(
550 proc_macro2::Span::call_site(),
551 "The #[tokio::main] macro requires rt or rt-multi-thread.",
552 )
553 .to_compile_error()
554 .into()
555}
556
557/// Always fails with the error message below.
558/// ```text
559/// The #[tokio::test] macro requires rt or rt-multi-thread.
560/// ```
561#[proc_macro_attribute]
562pub fn test_fail(_args: TokenStream, _item: TokenStream) -> TokenStream {
563 syn::Error::new(
564 proc_macro2::Span::call_site(),
565 "The #[tokio::test] macro requires rt or rt-multi-thread.",
566 )
567 .to_compile_error()
568 .into()
569}
570
571/// Implementation detail of the `select!` macro. This macro is **not** intended
572/// to be used as part of the public API and is permitted to change.
573#[proc_macro]
574#[doc(hidden)]
575pub fn select_priv_declare_output_enum(input: TokenStream) -> TokenStream {
576 select::declare_output_enum(input)
577}
578
579/// Implementation detail of the `select!` macro. This macro is **not** intended
580/// to be used as part of the public API and is permitted to change.
581#[proc_macro]
582#[doc(hidden)]
583pub fn select_priv_clean_pattern(input: TokenStream) -> TokenStream {
584 select::clean_pattern_macro(input)
585}