use crate::async_rt;
use crate::error::{ZmqError, ZmqResult};
use thiserror::Error;
#[derive(Error, Debug)]
pub enum TaskError {
#[error("Internal task error: {0}")]
Internal(#[from] Box<ZmqError>),
#[error("Task panicked")]
Panic,
#[error("Task cancelled")]
Cancelled,
}
impl From<async_rt::task::JoinError> for TaskError {
fn from(err: async_rt::task::JoinError) -> Self {
if err.is_panic() {
TaskError::Panic
} else {
debug_assert!(err.is_cancelled());
TaskError::Cancelled
}
}
}
pub struct TaskHandle<T> {
stop_channel: futures::channel::oneshot::Sender<()>,
join_handle: async_rt::task::JoinHandle<ZmqResult<T>>,
}
impl<T> TaskHandle<T> {
#[allow(unused)]
pub(crate) fn new(
stop_channel: futures::channel::oneshot::Sender<()>,
join_handle: async_rt::task::JoinHandle<ZmqResult<T>>,
) -> Self {
Self {
stop_channel,
join_handle,
}
}
#[allow(dead_code)]
pub(crate) async fn shutdown(self) -> ZmqResult<T> {
let _ = self.stop_channel.send(());
let join_result = self.join_handle.await.map_err(TaskError::from);
match join_result {
Ok(Ok(ok)) => Ok(ok),
Ok(Err(zmq_err)) => Err(zmq_err),
Err(task_err) => Err(task_err.into()),
}
}
}