use actix::{dev::MessageResponse, prelude::*};
use hitbox::{CacheError, Cacheable};
pub trait IntoCache: Cacheable {
fn into_cache<A>(self, upstream: &Addr<A>) -> QueryCache<A, Self>
where
A: Actor,
Self: Message + Send + Sized,
Self::Result: MessageResponse<A, Self> + Send + 'static,
{
QueryCache {
upstream: upstream.clone(),
message: self,
}
}
}
impl<M: Message + Cacheable> IntoCache for M {}
pub struct QueryCache<A, M>
where
M: Message + Cacheable + Send,
M::Result: MessageResponse<A, M> + Send,
A: Actor,
{
pub(crate) upstream: Addr<A>,
pub(crate) message: M,
}
impl<A, M> QueryCache<A, M>
where
M: Message + Cacheable + Send,
M::Result: MessageResponse<A, M> + Send,
A: Actor,
{
pub(crate) fn upstream_name(&self) -> &'static str {
std::any::type_name::<A>()
.rsplit("::")
.next()
.unwrap_or("<Unknown>")
}
pub fn cache_key(&self) -> Result<String, CacheError> {
Ok(format!(
"{}::{}",
self.upstream_name(),
self.message.cache_key()?
))
}
}
impl<'a, A, M> Message for QueryCache<A, M>
where
A: Actor,
M: Message + Cacheable + Send,
M::Result: MessageResponse<A, M> + Send,
{
type Result = Result<<M as Message>::Result, CacheError>;
}