diff --git a/.gitignore b/.gitignore index b0e1363..ba28109 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ .vscode/ test/ .workspace/ +expand.rs diff --git a/Cargo.lock b/Cargo.lock index d5f1a70..8b9003b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -976,6 +976,41 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" +dependencies = [ + "autocfg", + "num-traits", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -986,6 +1021,29 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.15" @@ -1080,6 +1138,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "944553dd59c802559559161f9816429058b869003836120e262e8caec061b7ae" +[[package]] +name = "parse_duration" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7037e5e93e0172a5a96874380bf73bc6ecef022e26fa25f2be26864d6b3ba95d" +dependencies = [ + "lazy_static", + "num", + "regex", +] + [[package]] name = "peeking_take_while" version = "0.1.2" @@ -1212,6 +1281,7 @@ dependencies = [ name = "proc_macros" version = "0.0.1" dependencies = [ + "parse_duration", "quote", "syn", ] diff --git a/proc_macros/Cargo.toml b/proc_macros/Cargo.toml index 68ca6f6..f70487c 100644 --- a/proc_macros/Cargo.toml +++ b/proc_macros/Cargo.toml @@ -11,5 +11,6 @@ path = "proc_macros.rs" proc-macro = true [dependencies] +parse_duration = "2" quote = "1" -syn = "1" +syn = { version = "1", features = ["full"] } diff --git a/proc_macros/proc_macros.rs b/proc_macros/proc_macros.rs index 4fae577..50d25d0 100644 --- a/proc_macros/proc_macros.rs +++ b/proc_macros/proc_macros.rs @@ -1,3 +1,4 @@ +extern crate parse_duration; extern crate quote; extern crate syn; @@ -5,6 +6,9 @@ use proc_macro::TokenStream; use quote::quote; use syn::parse_macro_input; use syn::Ident; +use syn::ItemFn; +use syn::LitInt; +use syn::LitStr; #[proc_macro] pub fn define_struct_reader_fn(item: TokenStream) -> TokenStream { @@ -79,3 +83,31 @@ pub fn impl_struct_writer_write(item: TokenStream) -> TokenStream { }; stream.into() } + +#[proc_macro_attribute] +pub fn async_timeout_test(attr: TokenStream, item: TokenStream) -> TokenStream { + let ItemFn { + attrs, + vis, + sig, + block, + } = parse_macro_input!(item as ItemFn); + let meta = parse_macro_input!(attr as LitStr); + let dura = parse_duration::parse(meta.value().as_str()).unwrap(); + let secs = LitInt::new(format!("{}", dura.as_secs()).as_str(), sig.ident.span()); + let nanos = LitInt::new( + format!("{}", dura.subsec_nanos()).as_str(), + sig.ident.span(), + ); + let stmts = &block.stmts; + let stream = quote! { + #(#attrs)* #vis #sig { + let dura = std::time::Duration::new(#secs, #nanos); + let f = async { + #(#stmts)* + }; + tokio::time::timeout(dura, f).await.unwrap(); + } + }; + stream.into() +} diff --git a/src/downloader/downloader.rs b/src/downloader/downloader.rs index 1c934b8..96a909a 100644 --- a/src/downloader/downloader.rs +++ b/src/downloader/downloader.rs @@ -679,6 +679,7 @@ impl Drop for Dow } } +#[proc_macros::async_timeout_test("100s")] #[tokio::test(flavor = "multi_thread", worker_threads = 4)] async fn test_downloader() { let p = Path::new("./test"); @@ -720,6 +721,7 @@ async fn test_downloader() { } } +#[proc_macros::async_timeout_test("60s")] #[tokio::test(flavor = "multi_thread", worker_threads = 4)] async fn test_failed_downloader() { let p = Path::new("./test"); @@ -756,6 +758,7 @@ async fn test_failed_downloader() { } } +#[proc_macros::async_timeout_test("60s")] #[tokio::test(flavor = "multi_thread", worker_threads = 4)] async fn test_downloader_dropped() { let p = Path::new("./test");