tokio_timeout/
lib.rs

1use proc_macro::TokenStream;
2
3/// # Timeout macro
4///
5/// A proc macro attribute that can be put on an async function, running within a
6/// tokio runtime, with the feature `time` enabled, which wraps the function in `tokio::time::timeout`
7///
8/// ```
9/// #[tokio_timeout::timeout(duration = "1s", on_error = "panic")]
10/// async fn my_fn() {
11///     println!("hello!");
12/// }
13/// ```
14///
15/// It takes two mandatory arguments 'duration' and 'on_error'.
16///
17/// ## Duration
18///
19/// 'Duration' can be either a string-literal that specifies a duration,
20/// valid values are `<n>h` for hours, `<n>m` for minutes, `<n>s` for seconds, and `<n>ms`
21/// for milliseconds. They can be chained together.
22///
23/// ```
24/// #[tokio_timeout::timeout(duration = "5h4m3s2ms", on_error = "panic")]
25/// async fn my_fn() {
26///     println!("hello!");
27/// }
28/// ```
29///
30/// Duration can also be specified to be some constant
31///
32/// ```
33/// use std::time::Duration;
34///
35/// const MY_DUR: Duration = Duration::from_millis(55);
36///
37/// #[tokio_timeout::timeout(duration = MY_DUR, on_error = "panic")]
38/// async fn my_fn() {
39///     println!("hello!");
40/// }
41/// ```
42///
43/// ## On error
44///
45/// On error can either be the string literal "panic", as seen in examples above,
46/// or something that can be invoked with a `&'static str` to produce an error.
47///
48/// ```
49///
50/// fn to_error_result(s: &str) -> Result<(), String>{
51///    Err(s.to_string())
52/// }
53///
54/// #[tokio_timeout::timeout(duration = "5h4m3s2ms", on_error = to_error_result)]
55/// async fn my_fn_string_err() -> Result<(), String>{
56///     println!("hello!");
57///     Ok(())
58/// }
59///
60/// pub enum MyErr {
61///     Timeout(&'static str)
62/// }
63///
64/// const fn to_error_enum(s: &'static str) -> Result<(), MyErr> {
65///     Err(MyErr::Timeout(s))
66/// }
67///
68/// #[tokio_timeout::timeout(duration = "5h4m3s2ms", on_error = to_error_enum)]
69/// async fn my_fn_enum_err() -> Result<(), MyErr>{
70///     println!("hello!");
71///     Ok(())
72/// }
73///
74/// fn print_err(s: &'static str) {
75///     eprintln!("oh no: {s}")
76/// }
77///
78/// #[tokio_timeout::timeout(duration = "5h4m3s2ms", on_error = print_err)]
79/// async fn my_print_timeout_fn() {
80///     println!("hello!");
81/// }
82///
83/// #[tokio_timeout::timeout(duration = "5h4m3s2ms", on_error = anyhow::bail!)]
84/// async fn anyhow_err_fn() -> anyhow::Result<()> {
85///     println!("hello!");
86///     Ok(())
87/// }
88///
89/// ```
90///
91/// ```compile_fail
92/// #[tokio_timeout::timeout]
93/// async fn both_attrs_needed() {}
94/// ```
95///
96/// ```compile_fail
97/// #[tokio_timeout::timeout]
98/// fn only_async_functions() {}
99/// ```
100///
101/// ```compile_fail
102/// #[tokio_timeout::timeout(duration = "1z", on_error = "panic")]
103/// async fn unrecognized_duration() {}
104/// ```
105///
106/// ```compile_fail
107/// #[tokio_timeout::timeout(duration = "1s", on_error = "panico")]
108/// async fn unrecognized_on_error() {}
109/// ```
110///
111#[proc_macro_attribute]
112pub fn timeout(attr: TokenStream, item: TokenStream) -> TokenStream {
113    timeout_macro_parse::tokio_timeout(attr, item)
114}