#![no_std]
extern crate alloc;
mod funcs;
mod macros;
mod traits;
pub use funcs::*;
pub use traits::*;
#[cfg(test)]
mod tests {
use alloc::sync::Arc;
use tokio::sync::{Barrier, Notify};
use super::*;
#[tokio::test]
async fn get() {
let notify = Arc::new(Notify::new());
let barrier = Arc::new(Barrier::new(11));
let get_notified = get!(fn(n: &mut Arc<Notify>) -> () {
n.notified()
});
for _ in 0..10 {
let barrier = barrier.clone();
let notified = get_notified.apply_to(notify.clone());
tokio::spawn(async move {
notified.await;
barrier.wait().await;
});
}
notify.notify_waiters();
barrier.wait().await;
}
#[tokio::test]
async fn try_get() {
let notify = Arc::new(Notify::new());
let barrier = Arc::new(Barrier::new(11));
let get_notified = try_get!(fn(n: &mut Arc<Notify>) -> Result<((), ()), ()> {
Ok((n.notified(), ()))
});
for _ in 0..10 {
let barrier = barrier.clone();
let notified = match get_notified.apply_to(notify.clone()) {
Ok((notified, ())) => notified,
Err((_notify, ())) => unreachable!(),
};
tokio::spawn(async move {
notified.await;
barrier.wait().await;
});
}
notify.notify_waiters();
barrier.wait().await;
}
#[cfg(feature = "async")]
#[tokio::test]
async fn async_try_get() {
use alloc::vec;
let notify = Arc::new(Notify::new());
let get_notified = async_try_get!(async fn(n: &mut Arc<Notify>) -> Result<((), ()), ()> {
Ok((n.notified(), ()))
});
let mut waiters = vec![];
for _ in 0..10 {
let notified = match get_notified.apply_to(notify.clone()).await {
Ok((notified, ())) => notified,
Err((_notify, ())) => unreachable!(),
};
waiters.push(async move {
notified.await;
})
}
notify.notify_waiters();
for waiter in waiters {
waiter.await
}
}
#[tokio::test]
async fn async_send_try_get() {
let notify = Arc::new(Notify::new());
let barrier = Arc::new(Barrier::new(11));
let get_notified = async_send_try_get!(fn<'a, 'b>(n: &mut Arc<Notify>) -> Result<((), ()), ()> {
async move {
let n = n.notified();
let v: Pin<Box<dyn 'b + Send + Future<Output = ()>>> = Box::pin(async move { n.await });
Ok((
v,
(),
))
}
});
for _ in 0..10 {
let barrier = barrier.clone();
let notified = match get_notified.apply_to(notify.clone()).await {
Ok((notified, ())) => notified,
Err((_notify, ())) => unreachable!(),
};
tokio::spawn(async move {
notified.await;
barrier.wait().await;
});
}
notify.notify_waiters();
barrier.wait().await;
}
}