# async_cell
The key type of this crate is `AsyncCell` which can be found in both thread-safe
and single-threaded variants. It is intended as a useful async primitive which
can replace more expensive channels in a fair number of cases.
> `AsyncCell<T>` behaves a lot like a `Cell<Option<T>>` that you can await on.
For example, it can be used to author futures in a callbacky style:
```rust
use async_cell::sync::AsyncCell;
let cell = AsyncCell::shared();
let future = cell.take_shared();
println!("{}", future.await);
```
In place of something like `tokio::sync::watch` to react to the latest value
of a variable:
```rust
use async_cell::sync::AsyncCell;
// Allocate space for our counter.
let counter_to_print = AsyncCell::shared();
// Try to print out the counts as fast as we receive them.
let c = counter_to_print.clone();
spawn(async move {
while let Some(count) = c.take().await {
println!("Latest count: {}", count);
}
});
// Begin counting!
for i in 0..1000 {
counter_to_print.set(Some(i));
}
counter_to_print.set(None);
```
To juggle a `Waker` within more complex data structures:
```rust
use async_cell::unsync::AsyncCell;
use std::cell::RefCell;
// A simple channel for sending numbers.
struct MpscStack {
ready: AsyncCell,
list: RefCell<Vec<i32>>,
}
impl MpscStack {
// Push a number to the end of the channel.
fn push(&self, x: i32) {
let mut list = self.list.borrow_mut();
if list.is_empty() {
self.ready.notify();
}
list.push(x);
}
// Pop a number off the end of the channel, blocking while it is empty.
async fn pop(&self) -> i32 {
loop {
if let Some(x) = self.list.borrow_mut().pop() {
return x;
}
self.ready.take().await;
}
}
}
```
Or can be used in place of a lazy_static + a oneshot channel to initialize
some resource:
```rust
use async_cell::sync::AsyncCell;
// AsyncCell::new() is const!
static DATA: AsyncCell<String> = AsyncCell::new();
// Read the file on a background thread.
DATA.set(hello);
});
// Do some work while waiting for the file.
// And ready!
assert_eq!(&DATA.take().await, "Hello, World!\n");
```
What can't async_cell do?
- Be used to broadcast data. If you need multiple concurrent consumers, get
yourself a channel.
- Guarantee that multiple sent values are received. When a cell is set in a
loop, the receiver might wake up only once, long after, and take the last.
Although this crate contains a number of utility functions, you should generally
be able to make due with just `AsyncCell::new`, `AsyncCell::set`, and
`AsyncCell::take`.