use std::any::{Any, TypeId};
use std::collections::HashMap;
use crate::Headers;
use super::dispatch::Delivery;
use super::publish::ScopedPublisher;
#[derive(Default)]
pub struct State {
map: HashMap<TypeId, Box<dyn Any + Send + Sync>>,
}
impl State {
pub fn insert<T: Any + Send + Sync>(&mut self, value: T) {
self.map.insert(TypeId::of::<T>(), Box::new(value));
}
#[must_use]
pub fn get<T: Any + Send + Sync>(&self) -> Option<&T> {
self.map.get(&TypeId::of::<T>())?.downcast_ref::<T>()
}
}
impl std::fmt::Debug for State {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("State")
.field("entries", &self.map.len())
.finish_non_exhaustive()
}
}
#[derive(Debug)]
pub struct Context<'a> {
name: &'a str,
headers: Headers,
state: &'a State,
delivery: &'a Delivery,
}
impl<'a> Context<'a> {
pub(crate) fn new(
name: &'a str,
headers: Headers,
state: &'a State,
delivery: &'a Delivery,
) -> Self {
Self {
name,
headers,
state,
delivery,
}
}
#[must_use]
pub fn name(&self) -> &str {
self.name
}
#[must_use]
pub fn publisher(&self, name: &str) -> Option<ScopedPublisher<'_>> {
let publisher = self.delivery.publishers.get(name)?;
Some(ScopedPublisher::new(
publisher.as_ref(),
&self.delivery.pipeline,
))
}
#[must_use]
pub fn headers(&self) -> &Headers {
&self.headers
}
pub fn headers_mut(&mut self) -> &mut Headers {
&mut self.headers
}
#[must_use]
pub fn get<T: Any + Send + Sync>(&self) -> Option<&T> {
self.state.get::<T>()
}
}