use std::collections::BTreeMap;
use crate::ValueCodecId;
use crate::ValueCodecRegistration;
use crate::ValueCodecRegistryError;
#[path = "value_codec_registry/value_bytes_codec_registry.rs"]
mod value_bytes_codec_registry;
#[path = "value_codec_registry/value_string_codec_registry.rs"]
mod value_string_codec_registry;
pub use value_bytes_codec_registry::ValueBytesCodecRegistry;
pub use value_string_codec_registry::ValueStringCodecRegistry;
#[derive(Debug)]
pub struct ValueCodecRegistry<D: 'static> {
registrations: Box<[ValueCodecRegistration<D>]>,
indices: BTreeMap<ValueCodecId, usize>,
}
impl<D: Copy + 'static> ValueCodecRegistry<D> {
pub fn from_registrations(
registrations: impl IntoIterator<Item = &'static ValueCodecRegistration<D>>,
) -> Result<Self, ValueCodecRegistryError> {
Self::build(registrations.into_iter().copied().collect())
}
#[must_use]
#[inline]
pub fn empty() -> Self {
Self {
registrations: Box::new([]),
indices: BTreeMap::new(),
}
}
pub(super) fn build(mut registrations: Vec<ValueCodecRegistration<D>>) -> Result<Self, ValueCodecRegistryError> {
registrations.sort_by_key(ValueCodecRegistration::id);
for (index, pair) in registrations.windows(2).enumerate() {
if pair[0].id() == pair[1].id() {
let id = pair[0].id();
let mut sources = registrations[index..]
.iter()
.take_while(|registration| registration.id() == id)
.map(ValueCodecRegistration::source)
.collect::<Vec<_>>();
sources.sort_unstable();
return Err(ValueCodecRegistryError::DuplicateId {
id: id.as_str(),
sources,
});
}
}
let indices = registrations
.iter()
.enumerate()
.map(|(index, registration)| (registration.id(), index))
.collect();
Ok(Self {
registrations: registrations.into_boxed_slice(),
indices,
})
}
#[inline]
pub fn get(&self, id: &str) -> Option<&ValueCodecRegistration<D>> {
let index = *self.indices.get(id)?;
self.registrations.get(index)
}
#[must_use]
#[inline]
pub fn registrations(&self) -> &[ValueCodecRegistration<D>] {
&self.registrations
}
}