use std::{
any::Any,
fmt,
future::Future,
ops::{Deref, DerefMut},
pin::Pin,
task::{Context, Poll},
};
use tokio::task::{JoinError, JoinHandle};
mod dates;
pub(crate) use dates::DateTimeExt;
pub(crate) enum Never {}
#[derive(Debug)]
pub(crate) struct AbortOnDropHandle<T>(JoinHandle<T>);
impl<T> From<JoinHandle<T>> for AbortOnDropHandle<T> {
fn from(handle: JoinHandle<T>) -> Self {
Self(handle)
}
}
impl<T> Deref for AbortOnDropHandle<T> {
type Target = JoinHandle<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for AbortOnDropHandle<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T> Future for AbortOnDropHandle<T> {
type Output = Result<T, JoinError>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Pin::new(&mut self.0).poll(cx)
}
}
impl<T> Drop for AbortOnDropHandle<T> {
fn drop(&mut self) {
self.0.abort();
}
}
#[derive(Debug)]
pub struct PanicPayload(String);
impl From<Box<dyn Any + Send>> for PanicPayload {
fn from(value: Box<dyn Any + Send>) -> Self {
let panic_msg = if let Some(s) = value.downcast_ref::<String>() {
s.clone()
} else if let Some(s) = value.downcast_ref::<&str>() {
s.to_string()
} else {
"unknown panic payload".to_string()
};
Self(panic_msg)
}
}
impl fmt::Display for PanicPayload {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}