use std::fmt::Debug;
use disqualified::ShortName;
use crate::{Scheduler, SchedulerHandle, SubscriptionLike, WorkCancellationId, WorkInvokeId};
#[derive(Default)]
pub struct Teardown {
teardown_fn: Option<Box<dyn FnOnce() + Send + Sync>>,
}
impl PartialEq for Teardown {
fn eq(&self, other: &Self) -> bool {
self.is_closed() == other.is_closed()
}
}
impl Debug for Teardown {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!(
"{} {{ is_closed: {} }}",
ShortName::of::<Self>(),
self.is_closed(),
))
}
}
impl Teardown {
pub fn new<F>(f: F) -> Self
where
F: 'static + FnOnce() + Send + Sync,
{
Self {
teardown_fn: Some(Box::new(f)),
}
}
pub fn new_from_box(f: Box<dyn FnOnce() + Send + Sync>) -> Self {
Self {
teardown_fn: Some(f),
}
}
#[inline]
pub fn new_work_cancellation<S: 'static + Scheduler>(
cancellation_id: WorkCancellationId,
scheduler: SchedulerHandle<S>,
) -> Self {
Teardown::new(move || scheduler.lock().cancel(cancellation_id))
}
#[inline]
pub fn new_work_invokation<S: 'static + Scheduler>(
invoke_id: WorkInvokeId,
scheduler: SchedulerHandle<S>,
) -> Self {
Teardown::new(move || scheduler.lock().invoke(invoke_id))
}
#[inline]
pub fn new_invoked_work_cancellation<S: 'static + Scheduler>(
invoke_id: WorkInvokeId,
scheduler: SchedulerHandle<S>,
) -> Self {
Teardown::new(move || scheduler.lock().cancel_invoked(invoke_id))
}
#[inline]
pub fn new_work_invokation_and_cancellation<S: 'static + Scheduler>(
invoke_id: WorkInvokeId,
cancellation_id: WorkCancellationId,
scheduler: SchedulerHandle<S>,
) -> Self {
Teardown::new(move || {
let mut scheduler = scheduler.lock();
scheduler.invoke(invoke_id);
scheduler.cancel(cancellation_id);
})
}
#[inline]
pub fn take(mut self) -> Option<Box<dyn FnOnce() + Send + Sync>> {
self.teardown_fn.take()
}
#[inline]
pub fn execute(mut self) {
if let Some(teardown) = self.teardown_fn.take() {
(teardown)();
}
}
#[inline]
pub fn is_closed(&self) -> bool {
self.teardown_fn.is_none()
}
}
impl<S> From<S> for Teardown
where
S: 'static + SubscriptionLike + Send + Sync,
{
fn from(mut subscription: S) -> Self {
Self {
teardown_fn: if subscription.is_closed() {
None
} else {
let closure = move || subscription.unsubscribe();
Some(Box::new(closure))
},
}
}
}