use std::any::{Any, TypeId};
pub trait Task: Send + Sync + 'static {}
impl<T: Send + Sync + 'static> Task for T {}
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) enum RouteKey {
Static(TypeId),
Dyn(u64),
}
pub(crate) struct Envelope {
pub key: RouteKey,
pub type_name: &'static str,
pub payload: Box<dyn Any + Send + Sync>,
pub attempt: u32,
pub tried: TriedMask,
}
impl Envelope {
pub fn new<T: Task>(task: T) -> Self {
Envelope {
key: RouteKey::Static(TypeId::of::<T>()),
type_name: std::any::type_name::<T>(),
payload: Box::new(task),
attempt: 0,
tried: TriedMask::empty(),
}
}
pub fn new_dyn(key: u64, type_name: &'static str, payload: Box<dyn Any + Send + Sync>) -> Self {
Envelope {
key: RouteKey::Dyn(key),
type_name,
payload,
attempt: 0,
tried: TriedMask::empty(),
}
}
}
#[derive(Clone, Copy, Default)]
pub(crate) struct TriedMask(u64);
impl TriedMask {
pub fn empty() -> Self {
TriedMask(0)
}
pub fn contains(self, id: u16) -> bool {
id < 64 && self.0 & (1u64 << id) != 0
}
pub fn with(self, id: u16) -> Self {
if id < 64 {
TriedMask(self.0 | (1u64 << id))
} else {
self
}
}
}