diff --git a/Cargo.toml b/Cargo.toml index 9f1494f..47cc70b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ autoexamples = false [features] -default = ["async-exec", "iouring"] +default = ["async-exec", "iouring", "attributes"] # Devs should enable these features to use iouring on linux. #default = ["asyncstd", "iouring"] epoll = [] @@ -41,7 +41,10 @@ iouring = ["rustix-uring", "rustix"] async-exec = ["async-global-executor"] tokio = ["async-global-executor/tokio"] +attributes = ["nuclei-attributes"] + [dependencies] +nuclei-attributes = { version = "0.1", optional = true } lever = "0.1" futures = { version = "0.3", default-features = false, features = ["std", "async-await"] } socket2 = { version = "0.3.19", features = ["pair", "unix"] } diff --git a/examples/Cargo.toml b/examples/Cargo.toml index e2418c3..7d217c6 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dev-dependencies] #nuclei = { path = "../" } -nuclei = { path = "../", default-features = false, features = ["tokio", "iouring"]} +nuclei = { path = "../", default-features = false, features = ["tokio", "iouring", "attributes"]} futures = { version = "0.3", default-features = false, features = ["std", "async-await"] } futures-util = "0.3" anyhow = "1.0.31" diff --git a/examples/fread-vect.rs b/examples/fread-vect.rs index 4921def..dcc1d63 100644 --- a/examples/fread-vect.rs +++ b/examples/fread-vect.rs @@ -9,29 +9,28 @@ use futures::AsyncReadExt; const IOVEC_WIDTH: usize = 1 << 10; -fn main() -> io::Result<()> { - let x = drive(async { - let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - path.push("data"); - path.push("quark-gluon-plasma"); - - let mut buf1 = [0; IOVEC_WIDTH]; - let mut buf2 = [0; IOVEC_WIDTH]; - let mut buf3 = [0; IOVEC_WIDTH]; - let mut bufs = [ - IoSliceMut::new(&mut buf1), - IoSliceMut::new(&mut buf2), - IoSliceMut::new(&mut buf3), - ]; - - let fo = File::open(&path).unwrap(); - let mut file = Handle::::new(fo).unwrap(); - file.read_vectored(&mut bufs[..]).await.unwrap(); - - vec![buf1, buf2, buf3] - }); - - x.iter().enumerate().for_each(|(idx, e)| { +#[nuclei::main] +async fn main() -> io::Result<()> { + let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + path.push("data"); + path.push("quark-gluon-plasma"); + + let mut buf1 = [0; IOVEC_WIDTH]; + let mut buf2 = [0; IOVEC_WIDTH]; + let mut buf3 = [0; IOVEC_WIDTH]; + let mut bufs = [ + IoSliceMut::new(&mut buf1), + IoSliceMut::new(&mut buf2), + IoSliceMut::new(&mut buf3), + ]; + + let fo = File::open(&path).unwrap(); + let mut file = Handle::::new(fo).unwrap(); + file.read_vectored(&mut bufs[..]).await.unwrap(); + + let bufs = vec![buf1, buf2, buf3]; + + bufs.iter().enumerate().for_each(|(idx, e)| { println!( "::: iovec ::: {}, data ::: \n\n{}\n\n", idx, diff --git a/examples/fread.rs b/examples/fread.rs index d57293a..f7cc960 100644 --- a/examples/fread.rs +++ b/examples/fread.rs @@ -6,23 +6,19 @@ use std::path::PathBuf; use futures::AsyncReadExt; -fn main() -> io::Result<()> { - let x: io::Result = drive(async { - let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - path.push("data"); - path.push("quark-gluon-plasma"); - dbg!(&path); +#[nuclei::main] +async fn main() -> io::Result<()> { + let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + path.push("data"); + path.push("quark-gluon-plasma"); - let fo = File::open(&path).unwrap(); - let mut file = Handle::::new(fo).unwrap(); - let mut buffer = String::new(); - file.read_to_string(&mut buffer).await?; - Ok(buffer) - }); - let x = x?; + let fo = File::open(&path).unwrap(); + let mut file = Handle::::new(fo).unwrap(); + let mut buffer = String::new(); + file.read_to_string(&mut buffer).await?; - println!("Content: {}", x); - println!("Length of file is {}", x.len()); + println!("Content: {}", buffer); + println!("Length of file is {}", buffer.len()); Ok(()) } diff --git a/examples/fwrite-vect.rs b/examples/fwrite-vect.rs index 48e1071..a6e33f0 100644 --- a/examples/fwrite-vect.rs +++ b/examples/fwrite-vect.rs @@ -12,40 +12,39 @@ use std::io::{IoSlice, SeekFrom}; const IOVEC_WIDTH: usize = 1 << 10; -fn main() -> io::Result<()> { - let x = drive(async { - let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - path.push("data"); - path.push("dark-matter-vect"); - - let buf1 = [0x41; IOVEC_WIDTH]; - let buf2 = [0x42; IOVEC_WIDTH]; - let buf3 = [0x43; IOVEC_WIDTH]; - let bufs = [ - IoSlice::new(&buf1), - IoSlice::new(&buf2), - IoSlice::new(&buf3), - ]; - - let fo = OpenOptions::new() - .read(true) - .write(true) - .open(&path) - .unwrap(); - let mut file = Handle::::new(fo).unwrap(); - file.write_vectored(&bufs[..]).await.unwrap(); - - let mut bufv = String::new(); - assert!(file.seek(SeekFrom::Start(0)).await.is_ok()); - file.read_to_string(&mut bufv).await.unwrap(); - bufv - }); - - assert_eq!(x.matches('A').count(), IOVEC_WIDTH); - assert_eq!(x.matches('B').count(), IOVEC_WIDTH); - assert_eq!(x.matches('C').count(), IOVEC_WIDTH); - - println!("SG write was: {}", x); +#[nuclei::main] +async fn main() -> io::Result<()> { + let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + path.push("data"); + path.push("dark-matter-vect"); + + let buf1 = [0x41; IOVEC_WIDTH]; + let buf2 = [0x42; IOVEC_WIDTH]; + let buf3 = [0x43; IOVEC_WIDTH]; + let bufs = [ + IoSlice::new(&buf1), + IoSlice::new(&buf2), + IoSlice::new(&buf3), + ]; + + let fo = OpenOptions::new() + .read(true) + .write(true) + .open(&path) + .unwrap(); + let mut file = Handle::::new(fo).unwrap(); + file.write_vectored(&bufs[..]).await.unwrap(); + + let mut bufv = String::new(); + assert!(file.seek(SeekFrom::Start(0)).await.is_ok()); + file.read_to_string(&mut bufv).await.unwrap(); + + + assert_eq!(bufv.matches('A').count(), IOVEC_WIDTH); + assert_eq!(bufv.matches('B').count(), IOVEC_WIDTH); + assert_eq!(bufv.matches('C').count(), IOVEC_WIDTH); + + println!("SG write was: {}", bufv); Ok(()) } diff --git a/examples/fwrite.rs b/examples/fwrite.rs index 9c377b0..314d03d 100644 --- a/examples/fwrite.rs +++ b/examples/fwrite.rs @@ -22,31 +22,30 @@ to detect.[1]\ \ "; -fn main() -> io::Result<()> { +#[nuclei::main] +async fn main() -> io::Result<()> { // Approximately ~75,9 MB let dark_matter = vec![DARK_MATTER_TEXT; 100_000].join("\n"); - let x = drive(async { - let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - path.push("data"); - path.push("dark-matter"); - - let fo = OpenOptions::new() - .read(true) - .write(true) - .open(&path) - .unwrap(); - let mut file = Handle::::new(fo).unwrap(); - file.write_all(dark_matter.as_bytes()).await.unwrap(); - - let mut buf = vec![]; - assert!(file.seek(SeekFrom::Start(0)).await.is_ok()); - assert_eq!(file.read_to_end(&mut buf).await.unwrap(), dark_matter.len()); - assert_eq!(&buf[0..dark_matter.len()], dark_matter.as_bytes()); - buf - }); - - println!("Length of file is {}", x.len()); + let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + path.push("data"); + path.push("dark-matter"); + + let fo = OpenOptions::new() + .read(true) + .write(true) + .open(&path) + .unwrap(); + let mut file = Handle::::new(fo).unwrap(); + file.write_all(dark_matter.as_bytes()).await.unwrap(); + + let mut buf = vec![]; + assert!(file.seek(SeekFrom::Start(0)).await.is_ok()); + assert_eq!(file.read_to_end(&mut buf).await.unwrap(), dark_matter.len()); + assert_eq!(&buf[0..dark_matter.len()], dark_matter.as_bytes()); + + + println!("Length of file is {}", buf.len()); Ok(()) } diff --git a/examples/h1-server-multishot.rs b/examples/h1-server-multishot.rs index 8df8b8e..b9af6b9 100644 --- a/examples/h1-server-multishot.rs +++ b/examples/h1-server-multishot.rs @@ -1,5 +1,6 @@ #[cfg(target_os = "linux")] -fn main() -> anyhow::Result<()> { +#[nuclei::main] +async fn main() -> anyhow::Result<()> { use nuclei::*; use std::net::TcpListener; @@ -51,14 +52,10 @@ fn main() -> anyhow::Result<()> { Ok(()) } - spawn_blocking(|| drive(future::pending::<()>())).detach(); + let http = listen(Handle::::bind("0.0.0.0:8000")?); - block_on(async { - let http = listen(Handle::::bind("0.0.0.0:8000")?); - - http.await?; - Ok(()) - }) + http.await?; + Ok(()) } #[cfg(target_os = "macos")] diff --git a/examples/h1-server.rs b/examples/h1-server.rs index e2c8cfc..ca91701 100644 --- a/examples/h1-server.rs +++ b/examples/h1-server.rs @@ -40,13 +40,10 @@ async fn listen(listener: Handle) -> Result<()> { } } -fn main() -> Result<()> { - spawn_blocking(|| drive(future::pending::<()>())).detach(); +#[nuclei::main] +async fn main() -> Result<()> { + let http = listen(Handle::::bind("0.0.0.0:8000")?); - block_on(async { - let http = listen(Handle::::bind("0.0.0.0:8000")?); - - http.await?; - Ok(()) - }) + http.await?; + Ok(()) } diff --git a/examples/tcp-client.rs b/examples/tcp-client.rs index 303a3ce..165ace8 100644 --- a/examples/tcp-client.rs +++ b/examples/tcp-client.rs @@ -3,15 +3,14 @@ use nuclei::*; use std::io; use std::net::TcpStream; -fn main() -> io::Result<()> { - drive(async { - println!("Connecting to server"); - let mut stream = Handle::::connect("127.0.0.1:7000").await?; - println!("Connected to {}", stream.get_ref().peer_addr()?); +#[nuclei::main] +async fn main() -> io::Result<()> { + println!("Connecting to server"); + let mut stream = Handle::::connect("127.0.0.1:7000").await?; + println!("Connected to {}", stream.get_ref().peer_addr()?); - let result = stream.write(b"hello world\n").await; - println!("Wrote, success={:?}", result.is_ok()); + let result = stream.write(b"hello world\n").await; + println!("Wrote, success={:?}", result.is_ok()); - Ok(()) - }) + Ok(()) } diff --git a/examples/tcp-server.rs b/examples/tcp-server.rs index 7ba8dfc..69d7423 100644 --- a/examples/tcp-server.rs +++ b/examples/tcp-server.rs @@ -7,20 +7,19 @@ async fn echo(stream: Handle) -> io::Result<()> { Ok(()) } -fn main() -> io::Result<()> { - drive(async { - // Create a listener. - let listener = Handle::::bind("0.0.0.0:7000")?; - println!("Listening on {}", listener.get_ref().local_addr()?); - println!("Now start a TCP client."); +#[nuclei::main] +async fn main() -> io::Result<()> { + // Create a listener. + let listener = Handle::::bind("0.0.0.0:7000")?; + println!("Listening on {}", listener.get_ref().local_addr()?); + println!("Now start a TCP client."); - // Accept clients in a loop. - loop { - let (stream, peer_addr) = listener.accept().await?; - println!("Accepted client: {:?}", peer_addr); + // Accept clients in a loop. + loop { + let (stream, peer_addr) = listener.accept().await?; + println!("Accepted client: {:?}", peer_addr); - // Spawn a task that echoes messages from the client back to it. - spawn(echo(stream)).detach(); - } - }) + // Spawn a task that echoes messages from the client back to it. + spawn(echo(stream)).detach(); + } } diff --git a/examples/unix-signal.rs b/examples/unix-signal.rs index 277ec14..d914a09 100644 --- a/examples/unix-signal.rs +++ b/examples/unix-signal.rs @@ -1,19 +1,18 @@ #[cfg(unix)] -fn main() -> std::io::Result<()> { +#[nuclei::main] +async fn main() -> std::io::Result<()> { use futures::prelude::*; use nuclei::*; use std::os::unix::net::UnixStream; - drive(async { - // Create a Unix stream that receives a byte on each signal occurrence. - let (a, mut b) = Handle::::pair()?; - signal_hook::pipe::register(signal_hook::SIGINT, a)?; - println!("Waiting for Ctrl-C..."); + // Create a Unix stream that receives a byte on each signal occurrence. + let (a, mut b) = Handle::::pair()?; + signal_hook::pipe::register(signal_hook::SIGINT, a)?; + println!("Waiting for Ctrl-C..."); - // Receive a byte that indicates the Ctrl-C signal occurred. - b.read_exact(&mut [0]).await?; + // Receive a byte that indicates the Ctrl-C signal occurred. + b.read_exact(&mut [0]).await?; - println!("Done!"); - Ok(()) - }) + println!("Done!"); + Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index eaeeae2..630296c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -82,3 +82,6 @@ mod syscore { pub use async_global_executor::*; pub use proactor::*; + +#[cfg(feature = "attributes")] +pub use nuclei_attributes::*; \ No newline at end of file diff --git a/src/proactor.rs b/src/proactor.rs index c4352cc..62f8874 100644 --- a/src/proactor.rs +++ b/src/proactor.rs @@ -99,7 +99,7 @@ pub fn drive(future: impl Future) -> T { } #[cfg(test)] -#[cfg(feature = "iouring")] +#[cfg(target_os = "linux")] mod proactor_tests { use crate::config::{IoUringConfiguration, NucleiConfig}; use crate::Proactor; diff --git a/testdata/dark-matter b/testdata/dark-matter index 8b13789..e69de29 100644 --- a/testdata/dark-matter +++ b/testdata/dark-matter @@ -1 +0,0 @@ - diff --git a/testdata/dark-matter-vect b/testdata/dark-matter-vect index 8b13789..e69de29 100644 --- a/testdata/dark-matter-vect +++ b/testdata/dark-matter-vect @@ -1 +0,0 @@ - diff --git a/tests/fread-vect.rs b/tests/fread-vect.rs index 22f7c69..092f483 100644 --- a/tests/fread-vect.rs +++ b/tests/fread-vect.rs @@ -8,30 +8,30 @@ use futures::AsyncReadExt; const IOVEC_WIDTH: usize = 1 << 10; -#[test] -fn read_vectored() { - let x = drive(async { - let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - path.push("testdata"); - path.push("quark-gluon-plasma"); - - let mut buf1 = [0; IOVEC_WIDTH]; - let mut buf2 = [0; IOVEC_WIDTH]; - let mut buf3 = [0; IOVEC_WIDTH]; - let mut bufs = [ - IoSliceMut::new(&mut buf1), - IoSliceMut::new(&mut buf2), - IoSliceMut::new(&mut buf3), - ]; - - let fo = File::open(&path).unwrap(); - let mut file = Handle::::new(fo).unwrap(); - file.read_vectored(&mut bufs[..]).await.unwrap(); - - vec![buf1, buf2, buf3] - }); - - x.iter().enumerate().for_each(|(_idx, e)| { +#[nuclei::test] +#[cfg(target_os = "linux")] +async fn read_vectored() { + let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + path.push("testdata"); + path.push("quark-gluon-plasma"); + + let mut buf1 = [0; IOVEC_WIDTH]; + let mut buf2 = [0; IOVEC_WIDTH]; + let mut buf3 = [0; IOVEC_WIDTH]; + let mut bufs = [ + IoSliceMut::new(&mut buf1), + IoSliceMut::new(&mut buf2), + IoSliceMut::new(&mut buf3), + ]; + + let fo = File::open(&path).unwrap(); + let mut file = Handle::::new(fo).unwrap(); + file.read_vectored(&mut bufs[..]).await.unwrap(); + + let bufs = vec![buf1, buf2, buf3]; + + + bufs.iter().enumerate().for_each(|(_idx, e)| { assert_eq!(IOVEC_WIDTH, String::from_utf8_lossy(&e[..]).len()); }); } diff --git a/tests/fread.rs b/tests/fread.rs index e6c9674..caae3da 100644 --- a/tests/fread.rs +++ b/tests/fread.rs @@ -3,19 +3,18 @@ use nuclei::*; use std::fs::File; use std::path::PathBuf; -#[test] -fn read_file() { - let x = drive(async { - let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - path.push("testdata"); - path.push("quark-gluon-plasma"); +#[nuclei::test] +async fn read_file() -> std::io::Result<()> { + let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + path.push("testdata"); + path.push("quark-gluon-plasma"); - let fo = File::open(&path).unwrap(); - let mut file = Handle::::new(fo).unwrap(); - let mut buffer = String::new(); - let _ = file.read_to_string(&mut buffer).await; - buffer - }); + let fo = File::open(&path).unwrap(); + let mut file = Handle::::new(fo).unwrap(); + let mut buffer = String::new(); + let _ = file.read_to_string(&mut buffer).await; - assert_eq!(11587, x.len()); + assert_eq!(11587, buffer.len()); + + Ok(()) } diff --git a/tests/fwrite-vect.rs b/tests/fwrite-vect.rs index 3cbfad6..8c4ac5f 100644 --- a/tests/fwrite-vect.rs +++ b/tests/fwrite-vect.rs @@ -2,8 +2,9 @@ /// Ref issue: https://github.com/rust-lang/rust/issues/68041 /// This should work fine with iouring. #[cfg(feature = "iouring")] -#[test] -fn write_vectored() { +#[cfg(target_os = "linux")] +#[nuclei::test] +async fn write_vectored() { use nuclei::*; use std::fs::{File, OpenOptions}; use std::io; @@ -18,37 +19,36 @@ fn write_vectored() { const IOVEC_WIDTH: usize = 1 << 10; - let x = drive(async { - let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - path.push("testdata"); - path.push("dark-matter-vect"); - - let buf1 = [0x41; IOVEC_WIDTH]; - let buf2 = [0x42; IOVEC_WIDTH]; - let buf3 = [0x43; IOVEC_WIDTH]; - let mut bufs = [ - IoSlice::new(&buf1), - IoSlice::new(&buf2), - IoSlice::new(&buf3), - ]; - - let fo = OpenOptions::new() - .read(true) - .write(true) - .open(&path) - .unwrap(); - let mut file = Handle::::new(fo).unwrap(); - file.write_vectored(&bufs[..]).await.unwrap(); - - let mut bufv = String::new(); - assert!(file.seek(SeekFrom::Start(0)).await.is_ok()); - file.read_to_string(&mut bufv).await.unwrap(); - bufv - }); - - assert_eq!(x.matches('A').count(), IOVEC_WIDTH); - assert_eq!(x.matches('B').count(), IOVEC_WIDTH); - assert_eq!(x.matches('C').count(), IOVEC_WIDTH); - - println!("SG write was: {}", x); + + let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + path.push("testdata"); + path.push("dark-matter-vect"); + + let buf1 = [0x41; IOVEC_WIDTH]; + let buf2 = [0x42; IOVEC_WIDTH]; + let buf3 = [0x43; IOVEC_WIDTH]; + let mut bufs = [ + IoSlice::new(&buf1), + IoSlice::new(&buf2), + IoSlice::new(&buf3), + ]; + + let fo = OpenOptions::new() + .read(true) + .write(true) + .open(&path) + .unwrap(); + let mut file = Handle::::new(fo).unwrap(); + file.write_vectored(&bufs[..]).await.unwrap(); + + let mut bufv = String::new(); + assert!(file.seek(SeekFrom::Start(0)).await.is_ok()); + file.read_to_string(&mut bufv).await.unwrap(); + + + assert_eq!(bufv.matches('A').count(), IOVEC_WIDTH); + assert_eq!(bufv.matches('B').count(), IOVEC_WIDTH); + assert_eq!(bufv.matches('C').count(), IOVEC_WIDTH); + + println!("SG write was: {}", bufv); } diff --git a/tests/fwrite.rs b/tests/fwrite.rs index 9d5f640..b71daaa 100644 --- a/tests/fwrite.rs +++ b/tests/fwrite.rs @@ -21,30 +21,27 @@ to detect.[1]\ \ "; -#[test] -fn write_file() { +#[nuclei::test] +async fn write_file() { // Approximately ~75,9 MB let dark_matter = vec![DARK_MATTER_TEXT; 100_000].join("\n"); - let x = drive(async { - let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - path.push("testdata"); - path.push("dark-matter"); - - let fo = OpenOptions::new() - .read(true) - .write(true) - .open(&path) - .unwrap(); - let mut file = Handle::::new(fo).unwrap(); - file.write_all(dark_matter.as_bytes()).await.unwrap(); - - let mut buf = vec![]; - assert!(file.seek(SeekFrom::Start(0)).await.is_ok()); - assert_eq!(file.read_to_end(&mut buf).await.unwrap(), dark_matter.len()); - assert_eq!(&buf[0..dark_matter.len()], dark_matter.as_bytes()); - buf - }); - - assert_eq!(75899999, x.len()); + let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + path.push("testdata"); + path.push("dark-matter"); + + let fo = OpenOptions::new() + .read(true) + .write(true) + .open(&path) + .unwrap(); + let mut file = Handle::::new(fo).unwrap(); + file.write_all(dark_matter.as_bytes()).await.unwrap(); + + let mut buf = vec![]; + assert!(file.seek(SeekFrom::Start(0)).await.is_ok()); + assert_eq!(file.read_to_end(&mut buf).await.unwrap(), dark_matter.len()); + assert_eq!(&buf[0..dark_matter.len()], dark_matter.as_bytes()); + + assert_eq!(75899999, buf.len()); }