use alloc::string::ToString;
use alloc::sync::Arc;
use hashbrown::HashMap;
use super::adapter::WireAdapter;
use super::decoder::Decoder;
use super::error::DecodeError;
use super::source::WireSource;
use crate::encoding::Value;
pub struct TypeMap<Src: WireSource, S, B> {
entries: HashMap<Src::TypeKey, Arc<dyn Decoder<Src, S, B> + Send + Sync>>,
}
impl<Src: WireSource, S, B> TypeMap<Src, S, B> {
#[must_use]
pub fn new() -> Self {
Self {
entries: HashMap::new(),
}
}
pub fn register<D>(&mut self, key: Src::TypeKey, decoder: D) -> &mut Self
where
D: Decoder<Src, S, B> + Send + Sync + 'static,
{
self.entries.insert(key, Arc::new(decoder));
self
}
#[must_use]
pub fn with<D>(mut self, key: Src::TypeKey, decoder: D) -> Self
where
D: Decoder<Src, S, B> + Send + Sync + 'static,
{
self.register(key, decoder);
self
}
#[must_use]
pub fn len(&self) -> usize {
self.entries.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
}
impl<Src, S, B> TypeMap<Src, S, B>
where
Src: TypeMapDefaults<S, B>,
{
#[must_use]
pub fn defaults() -> Self {
<Src as TypeMapDefaults<S, B>>::defaults()
}
}
impl<Src: WireSource, S, B> Default for TypeMap<Src, S, B> {
fn default() -> Self {
Self::new()
}
}
impl<Src: WireSource, S, B> WireAdapter<Src, S, B> for TypeMap<Src, S, B> {
fn decode(&self, payload: Src::Payload<'_>) -> Result<Value<S, B>, DecodeError> {
let key = Src::type_key(&payload);
match self.entries.get(&key) {
Some(decoder) => decoder.decode(payload),
None => Err(DecodeError::NoDecoderForType {
column: Src::column_name(&payload).to_string(),
}),
}
}
}
pub trait TypeMapDefaults<S, B>: WireSource + Sized {
fn defaults() -> TypeMap<Self, S, B>;
}