async_cell::sync

Struct GuardedCell

Source
pub struct GuardedCell<T, C: Deref<Target = AsyncCell<T>>> { /* private fields */ }
Expand description

A utility wrapper to set a given AsyncCell<T> when dropped.

Implementations§

Source§

impl<T, C: Deref<Target = AsyncCell<T>>> GuardedCell<T, C>

Source

pub fn release(self)

Drop this guard without setting the wrapped cell.

Source

pub fn set(self, value: T)

Like AsyncCell::set but also releases this guard.

Source

pub fn or_set(self, value: T)

Like AsyncCell::or_set but also releases this guard.

Methods from Deref<Target = AsyncCell<T>>§

Source

pub fn set(&self, value: T)

Set the value of the cell. If it was previously empty, wake up a single arbitrary call take and/or all calls to get.

This is probably the most important function in the whole crate since it can be used to resolve some future X with some value Y at a distance.

use async_cell::sync::AsyncCell;

let cell = AsyncCell::shared();
let message = cell.take_shared();

spawn(async move {
    println!("{}", message.await)
});

cell.set("Hello, World!");
Source

pub fn take(&self) -> Take<&Self>

Once woken up with a value, remove it and resolve.

use async_cell::sync::AsyncCell;

let cell1 = AsyncCell::shared();
let cell2 = cell1.clone();

spawn(async move {
    cell1.set(vec![1i32, 2, 3]);
});

assert_eq!(&cell2.take().await, &[1, 2, 3]);

// Awaiting again on the cell would block forever!
// The value is now None.
assert_eq!(cell2.try_take(), None);

Technically, the returned type is just a reference to this cell. It must be driven by await to actually move the internal data. If borrowing this cell is unacceptable, consider directly constructing the Take wrapper around a smart-pointer of your own choosing.

Source

pub fn get(&self) -> Get<&Self>
where T: Clone,

Once woken up with a value, clone it and resolve.

use async_cell::sync::AsyncCell;

let cell1 = AsyncCell::shared();
let cell2 = cell1.clone();

spawn(async move {
    cell1.set(vec![1i32, 2, 3]);
});

assert_eq!(&cell2.get().await, &[1, 2, 3]);
assert_eq!(&cell2.get().await, &[1, 2, 3]);

Technically, the returned type is just a reference to this cell. It must be driven by await to actually move the internal data. If borrowing this cell is unacceptable, consider directly constructing the Get wrapper around a smart-pointer of your own choosing.

Source

pub fn try_take(&self) -> Option<T>

If the cell currently has a value, remove it.

use async_cell::sync::AsyncCell;

let cell = AsyncCell::new();

cell.set(420);

assert_eq!(cell.try_take(), Some(420));
assert_eq!(cell.try_take(), None);
Source

pub fn try_get(&self) -> Option<T>
where T: Clone,

Clones the current value of the cell.

use async_cell::sync::AsyncCell;

let cell = AsyncCell::new();

// Value starts out empty.
assert_eq!(cell.try_get(), None);

cell.set(420);

// Value is now set.
assert_eq!(cell.try_get(), Some(420));
Source

pub fn or_set(&self, value: T)

Set the value of the cell if it is empty, waking up any attached futures.

Source

pub fn is_set(&self) -> bool

Is the cell currently full?

Source

pub fn replace(&self, value: T) -> Option<T>

Replace the value of the cell, returning the previous value. If the previous value is empty, wake up any attached futures.

Source

pub fn update(&self, with: impl FnOnce(Option<T>) -> Option<T>)

Atomically update the value of this cell using the given function.

If the value transitions from None to Some, it acts like a call to set. Otherwise it only effects the internals of the cell.

Note: avoid doing anything time consuming in the passed function, since it will block any async runtime thread in the process of poll-ing a Get or Take future.

Source

pub fn update_some(&self, with: impl FnOnce(T) -> T)

Atomically update the value of this cell if it is set, using the given function.

Note: avoid doing anything time consuming in the passed function, since it will block any async runtime thread in the process of poll-ing a Get or Take future.

Source

pub fn guard(&self, cancel: T) -> GuardedCell<T, &Self>

Used to ensure this cell is set to some value even when panicking or returning errors. This is useful in preventing deadlocks, signaling shutdown, etc.

use async_cell::sync::AsyncCell;

let latest_val = AsyncCell::shared();

let latest_val_ref = latest_val.clone();
let read_content = move |path: &str| -> Option<u32> {
    let latest_val = latest_val_ref.guard(Err(format!("{:?} is not an int", path)));
    let text = std::fs::read_to_string(path).ok()?;
    let val = text.parse().ok()?;
    latest_val.set(Ok(val));
    Some(val)
};

spawn(async move {
    if let Some(val) = read_content("test/hello.txt") {
        send(val);
    }
});

match latest_val.get().await {
    Ok(text) => println!("{}", text),
    Err(text) => eprintln!("Error: {}", text),
}
Source

pub fn notify(&self)

Wake up a single arbitrary call to wait.

Source

pub fn wait(&self) -> Take<&AsyncCell>

Resolves once notify is called.

Source

pub fn wait_shared(self: &Arc<Self>) -> Take<Arc<AsyncCell>>

Resolves once notify is called.

Source

pub fn take_shared(self: &Arc<Self>) -> Take<Arc<Self>>

Like take but doesn’t borrow self.

Source

pub fn get_shared(self: &Arc<Self>) -> Get<Arc<Self>>
where T: Clone,

Like get but doesn’t borrow self.

Source

pub fn guard_shared(self: &Arc<Self>, cancel: T) -> GuardedCell<T, Arc<Self>>

Like guard but doesn’t borrow self.

Source

pub fn take_weak(self: &Arc<Self>) -> TakeWeak<T>

Like take but creates a weak reference to self. If all strong references to self are dropped, the returned future will resolve to None even if the cell was full at the time.

use async_cell::sync::AsyncCell;

let cell = AsyncCell::shared();
let taker = cell.take_weak();

// The cell can be used normally
cell.set(42);
assert_eq!((&taker).await, Some(42));

// Will resolve after being dropped
spawn(async move {
    cell.set(43); // any current value will be dropped
    drop(cell);
});
assert_eq!(taker.await, None);
Source

pub fn get_weak(self: &Arc<Self>) -> GetWeak<T>
where T: Clone,

Like get but creates a weak reference to self. If self is dropped, the returned future will resolve to None.

use async_cell::sync::AsyncCell;

let cell = AsyncCell::<i32>::shared();
let getter = cell.get_weak();

spawn(async move {
    cell.set(43); // any current value will be dropped
    drop(cell);
});
assert_eq!(getter.await, None);

Trait Implementations§

Source§

impl<T, C: Deref<Target = AsyncCell<T>>> Deref for GuardedCell<T, C>

Source§

type Target = AsyncCell<T>

The resulting type after dereferencing.
Source§

fn deref(&self) -> &AsyncCell<T>

Dereferences the value.
Source§

impl<T, C: Deref<Target = AsyncCell<T>>> Drop for GuardedCell<T, C>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<T, C> Freeze for GuardedCell<T, C>
where C: Freeze, T: Freeze,

§

impl<T, C> RefUnwindSafe for GuardedCell<T, C>

§

impl<T, C> Send for GuardedCell<T, C>
where C: Send, T: Send,

§

impl<T, C> Sync for GuardedCell<T, C>
where C: Sync, T: Sync,

§

impl<T, C> Unpin for GuardedCell<T, C>
where C: Unpin, T: Unpin,

§

impl<T, C> UnwindSafe for GuardedCell<T, C>
where C: UnwindSafe, T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.