use crate::error::RuntimeError;
use std::sync::Arc;
pub trait WorkListener: Send + Sync {
fn on_complete(&self);
fn on_interrupt(&self);
fn on_error(&self, _error: RuntimeError) {}
}
pub trait FixedCountProgress: Send + Sync {
fn on_progress(&self, current: u32, total: u32, tag: &str);
}
pub struct WorkListenerClosure<C, I, E> {
on_complete: C,
on_interrupt: I,
on_error: E,
}
impl<C, I, E> WorkListener for WorkListenerClosure<C, I, E>
where
C: Fn() + Send + Sync,
I: Fn() + Send + Sync,
E: Fn(RuntimeError) + Send + Sync,
{
fn on_complete(&self) {
(self.on_complete)();
}
fn on_interrupt(&self) {
(self.on_interrupt)();
}
fn on_error(&self, error: RuntimeError) {
(self.on_error)(error);
}
}
pub fn listener<C, I>(
on_complete: C,
on_interrupt: I,
) -> Arc<WorkListenerClosure<C, I, fn(RuntimeError)>>
where
C: Fn() + Send + Sync,
I: Fn() + Send + Sync,
{
Arc::new(WorkListenerClosure {
on_complete,
on_interrupt,
on_error: |_| {},
})
}
pub fn listener_with_error<C, I, E>(
on_complete: C,
on_interrupt: I,
on_error: E,
) -> Arc<WorkListenerClosure<C, I, E>>
where
C: Fn() + Send + Sync,
I: Fn() + Send + Sync,
E: Fn(RuntimeError) + Send + Sync,
{
Arc::new(WorkListenerClosure {
on_complete,
on_interrupt,
on_error,
})
}
impl<F> FixedCountProgress for F
where
F: Fn(u32, u32, &str) + Send + Sync,
{
fn on_progress(&self, current: u32, total: u32, tag: &str) {
self(current, total, tag);
}
}