use std::{
ops::Deref,
sync::Arc,
time::Duration,
};
use super::{
AsyncConditionWaiter,
AsyncMonitorFuture,
AsyncNotificationWaiter,
AsyncTimeoutConditionWaiter,
AsyncTimeoutNotificationWaiter,
Notifier,
TokioMonitor,
WaitTimeoutResult,
WaitTimeoutStatus,
};
pub struct ArcTokioMonitor<T> {
inner: Arc<TokioMonitor<T>>,
}
impl<T> ArcTokioMonitor<T> {
pub fn new(state: T) -> Self {
Self {
inner: Arc::new(TokioMonitor::new(state)),
}
}
pub async fn async_read<R, F>(&self, f: F) -> R
where
F: FnOnce(&T) -> R,
{
self.inner.async_read(f).await
}
pub async fn async_write<R, F>(&self, f: F) -> R
where
F: FnOnce(&mut T) -> R,
{
self.inner.async_write(f).await
}
pub async fn async_write_notify_one<R, F>(&self, f: F) -> R
where
F: FnOnce(&mut T) -> R,
{
self.inner.async_write_notify_one(f).await
}
pub async fn async_write_notify_all<R, F>(&self, f: F) -> R
where
F: FnOnce(&mut T) -> R,
{
self.inner.async_write_notify_all(f).await
}
pub fn notify_one(&self) {
self.inner.notify_one();
}
pub fn notify_all(&self) {
self.inner.notify_all();
}
}
impl<T> Notifier for ArcTokioMonitor<T> {
fn notify_one(&self) {
Self::notify_one(self);
}
fn notify_all(&self) {
Self::notify_all(self);
}
}
impl<T: Send> AsyncNotificationWaiter for ArcTokioMonitor<T> {
fn async_wait<'a>(&'a self) -> AsyncMonitorFuture<'a, ()> {
self.inner.async_wait()
}
}
impl<T: Send> AsyncTimeoutNotificationWaiter for ArcTokioMonitor<T> {
fn async_wait_for<'a>(
&'a self,
timeout: Duration,
) -> AsyncMonitorFuture<'a, WaitTimeoutStatus> {
self.inner.async_wait_for(timeout)
}
}
impl<T: Send> AsyncConditionWaiter for ArcTokioMonitor<T> {
type State = T;
fn async_wait_until<'a, R, P, F>(&'a self, predicate: P, action: F) -> AsyncMonitorFuture<'a, R>
where
R: Send + 'a,
P: FnMut(&Self::State) -> bool + Send + 'a,
F: FnOnce(&mut Self::State) -> R + Send + 'a,
{
self.inner.async_wait_until(predicate, action)
}
fn async_wait_while<'a, R, P, F>(&'a self, predicate: P, action: F) -> AsyncMonitorFuture<'a, R>
where
R: Send + 'a,
P: FnMut(&Self::State) -> bool + Send + 'a,
F: FnOnce(&mut Self::State) -> R + Send + 'a,
{
self.inner.async_wait_while(predicate, action)
}
}
impl<T: Send> AsyncTimeoutConditionWaiter for ArcTokioMonitor<T> {
fn async_wait_until_for<'a, R, P, F>(
&'a self,
timeout: Duration,
predicate: P,
action: F,
) -> AsyncMonitorFuture<'a, WaitTimeoutResult<R>>
where
R: Send + 'a,
P: FnMut(&Self::State) -> bool + Send + 'a,
F: FnOnce(&mut Self::State) -> R + Send + 'a,
{
self.inner.async_wait_until_for(timeout, predicate, action)
}
fn async_wait_while_for<'a, R, P, F>(
&'a self,
timeout: Duration,
predicate: P,
action: F,
) -> AsyncMonitorFuture<'a, WaitTimeoutResult<R>>
where
R: Send + 'a,
P: FnMut(&Self::State) -> bool + Send + 'a,
F: FnOnce(&mut Self::State) -> R + Send + 'a,
{
self.inner.async_wait_while_for(timeout, predicate, action)
}
}
impl<T> AsRef<TokioMonitor<T>> for ArcTokioMonitor<T> {
fn as_ref(&self) -> &TokioMonitor<T> {
self.inner.as_ref()
}
}
impl<T> Deref for ArcTokioMonitor<T> {
type Target = TokioMonitor<T>;
fn deref(&self) -> &Self::Target {
self.inner.as_ref()
}
}
impl<T> Clone for ArcTokioMonitor<T> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}
impl<T> From<T> for ArcTokioMonitor<T> {
fn from(value: T) -> Self {
Self::new(value)
}
}
impl<T: Default> Default for ArcTokioMonitor<T> {
fn default() -> Self {
Self::new(T::default())
}
}