#![feature(async_closure)] #![feature(never_type)] mod aliases; pub mod fs; pub mod net; mod plat; mod wove; use std::{future::Future, pin::Pin, task::Poll}; use aliases::IoResult; #[cfg(target_os = "linux")] pub(crate) use plat::linux as plat_impl; pub struct Tock(bool); impl Tock { fn new() -> Self { Self(false) } } impl Future for Tock { type Output = (); fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll { if self.0 { return Poll::Ready(()); } let this = unsafe { self.get_unchecked_mut() }; this.0 = true; cx.waker().wake_by_ref(); Poll::Pending } } pub struct Wove { platform: plat_impl::Platform, } impl Wove { pub fn new() -> IoResult { Ok(Self { platform: plat_impl::Platform::new()?, }) } pub async fn run(&self) -> IoResult { loop { self.platform.tick().await?; } } } #[cfg(test)] mod test { use std::path::PathBuf; use crate::Wove; use futures_lite::future::try_zip; #[test] fn sketch() { let mut wove = Wove::new().unwrap(); let wove = &mut wove; let fut = async { let run = async { wove.run().await?; }; let hello = crate::fs::read_to_string(wove, PathBuf::from("test_data/hello.txt")); let goodbye = crate::fs::read_to_string(wove, PathBuf::from("test_data/goodbye.txt")); let both = try_zip(hello, goodbye); let contents = futures_lite::future::race(both, run).await; contents }; let (hello, goodbye) = pollster::block_on(fut).unwrap(); assert_eq!(hello, "hello!\n"); assert_eq!(goodbye, "goodbye!\n"); } }