pub struct SharedObservable<T, L: Lock = SyncLock> { /* private fields */ }
Expand description

A value whose changes will be broadcast to subscribers.

Unlike Observable, SharedObservable can be Cloned but does’t dereference to T. Because of the latter, it has regular methods to access or modify the inner value.

Async-aware locking

If you want to write-lock the inner value over a .await point, that requires an async-aware lock. You can use new_async to create a SharedObservable<T, AsyncLock>, where most methods are async but in return locking the inner value over .await points becomes unproblematic.

Implementations§

source§

impl<T> SharedObservable<T>

source

pub fn new(value: T) -> Self

Create a new SharedObservable with the given initial value.

source

pub fn subscribe(&self) -> Subscriber<T>

Obtain a new subscriber.

Calling .next().await or .next_ref().await on the returned subscriber only resolves once the inner value has been updated again after the call to subscribe.

See subscribe_reset if you want to obtain a subscriber that immediately yields without any updates.

source

pub fn subscribe_reset(&self) -> Subscriber<T>

Obtain a new subscriber that immediately yields.

.subscribe_reset() is equivalent to .subscribe() with a subsequent call to .reset() on the returned subscriber.

In contrast to subscribe, calling .next().await or .next_ref().await on the returned subscriber before updating the inner value yields the current value instead of waiting. Further calls to either of the two will wait for updates.

source

pub fn get(&self) -> Twhere T: Clone,

Get a clone of the inner value.

source

pub fn read(&self) -> ObservableReadGuard<'_, T>

Lock the inner with shared read access, blocking the current thread until the lock can be acquired.

While the returned read guard is alive, nobody can update the inner value. If you want to update the value based on the previous value, do not use this method because it can cause races with other clones of the same SharedObservable. Instead, call of of the update_ methods, or if that doesn’t fit your use case, call write and update the value through the write guard it returns.

source

pub fn try_read(&self) -> TryLockResult<ObservableReadGuard<'_, T>>

Attempts to acquire shared read access to the inner value.

See RwLocks documentation for details.

source

pub fn write(&self) -> ObservableWriteGuard<'_, T>

Lock the inner with exclusive write access, blocking the current thread until the lock can be acquired.

This can be used to set a new value based on the existing value. The returned write guard dereferences (immutably) to the inner type, and has associated functions to update it.

source

pub fn try_write(&self) -> TryLockResult<ObservableWriteGuard<'_, T>>

Attempts to acquire exclusive write access to the inner value.

See RwLocks documentation for details.

source

pub fn set(&self, value: T) -> T

Set the inner value to the given value, notify subscribers and return the previous value.

source

pub fn set_if_not_eq(&self, value: T) -> Option<T>where T: PartialEq,

Set the inner value to the given value if it doesn’t compare equal to the existing value.

If the inner value is set, subscribers are notified and Some(previous_value) is returned. Otherwise, None is returned.

source

pub fn set_if_hash_not_eq(&self, value: T) -> Option<T>where T: Hash,

Set the inner value to the given value if it has a different hash than the existing value.

If the inner value is set, subscribers are notified and Some(previous_value) is returned. Otherwise, None is returned.

source

pub fn take(&self) -> Twhere T: Default,

Set the inner value to a Default instance of its type, notify subscribers and return the previous value.

Shorthand for observable.set(T::default()).

source

pub fn update(&self, f: impl FnOnce(&mut T))

Update the inner value and notify subscribers.

Note that even if the inner value is not actually changed by the closure, subscribers will be notified as if it was. Use update_if if you want to conditionally mutate the inner value.

source

pub fn update_if(&self, f: impl FnOnce(&mut T) -> bool)

Maybe update the inner value and notify subscribers if it changed.

The closure given to this function must return true if subscribers should be notified of a change to the inner value.

source§

impl<T: Send + Sync + 'static> SharedObservable<T, AsyncLock>

source

pub fn new_async(value: T) -> Self

Available on crate feature async-lock only.

Create a new async SharedObservable with the given initial value.

source

pub async fn subscribe(&self) -> Subscriber<T, AsyncLock>

Available on crate feature async-lock only.

Obtain a new subscriber.

Calling .next().await or .next_ref().await on the returned subscriber only resolves once the inner value has been updated again after the call to subscribe.

See subscribe_reset if you want to obtain a subscriber that immediately yields without any updates.

source

pub fn subscribe_reset(&self) -> Subscriber<T, AsyncLock>

Available on crate feature async-lock only.

Obtain a new subscriber that immediately yields.

.subscribe_reset() is equivalent to .subscribe() with a subsequent call to .reset() on the returned subscriber.

In contrast to subscribe, calling .next().await or .next_ref().await on the returned subscriber before updating the inner value yields the current value instead of waiting. Further calls to either of the two will wait for updates.

source

pub async fn get(&self) -> Twhere T: Clone,

Available on crate feature async-lock only.

Get a clone of the inner value.

source

pub async fn read(&self) -> ObservableReadGuard<'_, T, AsyncLock>

Available on crate feature async-lock only.

Read the inner value.

While the returned read guard is alive, nobody can update the inner value. If you want to update the value based on the previous value, do not use this method because it can cause races with other clones of the same SharedObservable. Instead, call of of the update_ methods, or if that doesn’t fit your use case, call write and update the value through the write guard it returns.

source

pub fn try_read(&self) -> Option<ObservableReadGuard<'_, T, AsyncLock>>

Available on crate feature async-lock only.

Attempts to acquire shared read access to the inner value.

If it is already locked for writing, returns None.

source

pub async fn write(&self) -> ObservableWriteGuard<'_, T, AsyncLock>

Available on crate feature async-lock only.

Get a write guard to the inner value.

This can be used to set a new value based on the existing value. The returned write guard dereferences (immutably) to the inner type, and has associated functions to update it.

source

pub fn try_write(&self) -> Option<ObservableWriteGuard<'_, T, AsyncLock>>

Available on crate feature async-lock only.

Attempts to acquire exclusive write access to the inner value.

If it is already locked, returns None.

source

pub async fn set(&self, value: T) -> T

Available on crate feature async-lock only.

Set the inner value to the given value, notify subscribers and return the previous value.

source

pub async fn set_if_not_eq(&self, value: T) -> Option<T>where T: PartialEq,

Available on crate feature async-lock only.

Set the inner value to the given value if it doesn’t compare equal to the existing value.

If the inner value is set, subscribers are notified and Some(previous_value) is returned. Otherwise, None is returned.

source

pub async fn set_if_hash_not_eq(&self, value: T) -> Option<T>where T: Hash,

Available on crate feature async-lock only.

Set the inner value to the given value if it has a different hash than the existing value.

If the inner value is set, subscribers are notified and Some(previous_value) is returned. Otherwise, None is returned.

source

pub async fn take(&self) -> Twhere T: Default,

Available on crate feature async-lock only.

Set the inner value to a Default instance of its type, notify subscribers and return the previous value.

Shorthand for observable.set(T::default()).

source

pub async fn update(&self, f: impl FnOnce(&mut T))

Available on crate feature async-lock only.

Update the inner value and notify subscribers.

Note that even if the inner value is not actually changed by the closure, subscribers will be notified as if it was. Use update_if if you want to conditionally mutate the inner value.

source

pub async fn update_if(&self, f: impl FnOnce(&mut T) -> bool)

Available on crate feature async-lock only.

Maybe update the inner value and notify subscribers if it changed.

The closure given to this function must return true if subscribers should be notified of a change to the inner value.

source§

impl<T, L: Lock> SharedObservable<T, L>

source

pub fn observable_count(&self) -> usize

Get the number of SharedObservable clones.

This always returns at least 1 since self is included in the count.

Be careful when using this. The result is only reliable if it is exactly 1, as otherwise it could be incremented right after your call to this function, before you look at its result or do anything based on that.

source

pub fn subscriber_count(&self) -> usize

Get the number of subscribers.

Be careful when using this. The result can change right after your call to this function, before you look at its result or do anything based on that.

source

pub fn strong_count(&self) -> usize

Get the number of strong references to the inner value.

Every clone of the SharedObservable and every associated Subscriber holds a reference, so this is the sum of all clones and subscribers. This always returns at least 1 since self is included in the count.

Equivalent to ob.observable_count() + ob.subscriber_count().

Be careful when using this. The result is only reliable if it is exactly 1, as otherwise it could be incremented right after your call to this function, before you look at its result or do anything based on that.

source

pub fn weak_count(&self) -> usize

Get the number of weak references to the inner value.

Weak references are created using downgrade or by cloning an existing weak reference.

source

pub fn downgrade(&self) -> WeakObservable<T, L>

Create a new WeakObservable reference to the same inner value.

Trait Implementations§

source§

impl<T, L: Lock> Clone for SharedObservable<T, L>

source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T, L: Lock> Debug for SharedObservable<T, L>where L::RwLock<ObservableState<T>>: Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T, L> Default for SharedObservable<T, L>where T: Default, L: Lock,

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl<T, L: Lock> Drop for SharedObservable<T, L>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<T, L> RefUnwindSafe for SharedObservable<T, L>where <L as Lock>::RwLock<ObservableState<T>>: RefUnwindSafe,

§

impl<T, L> Send for SharedObservable<T, L>where <L as Lock>::RwLock<ObservableState<T>>: Send + Sync,

§

impl<T, L> Sync for SharedObservable<T, L>where <L as Lock>::RwLock<ObservableState<T>>: Send + Sync,

§

impl<T, L> Unpin for SharedObservable<T, L>

§

impl<T, L> UnwindSafe for SharedObservable<T, L>where <L as Lock>::RwLock<ObservableState<T>>: RefUnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere 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> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere 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<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

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

§

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 Twhere U: TryFrom<T>,

§

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.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more