use {
crate::source::{Source, SourceError},
alloc::{boxed::Box, vec::Vec},
core::fmt::{self, Debug},
maybe_sync::Rc,
};
pub struct RegistryBuilder<K: ?Sized> {
storages: Vec<Box<dyn Source<K>>>,
}
impl<K> Default for RegistryBuilder<K>
where
K: ?Sized,
{
fn default() -> Self {
Self::new()
}
}
impl<K> RegistryBuilder<K>
where
K: ?Sized,
{
pub fn new() -> Self {
RegistryBuilder {
storages: Vec::new(),
}
}
pub fn with(mut self, storage: impl Source<K>) -> Self {
self.add(storage);
self
}
pub fn add(&mut self, storage: impl Source<K>) -> &mut Self {
self.storages.push(Box::new(storage));
self
}
pub fn build(self) -> Registry<K> {
Registry {
storages: self.storages.into(),
}
}
}
pub struct Registry<K: ?Sized> {
storages: Rc<[Box<dyn Source<K>>]>,
}
impl<K> Clone for Registry<K>
where
K: ?Sized,
{
fn clone(&self) -> Self {
Registry {
storages: self.storages.clone(),
}
}
}
impl<K> Registry<K>
where
K: 'static,
{
pub fn builder() -> RegistryBuilder<K> {
RegistryBuilder::new()
}
pub async fn read(self, key: K) -> Result<Vec<u8>, SourceError> {
for storage in &*self.storages {
match storage.read(&key).await {
Err(SourceError::NotFound) => continue,
result => return result,
}
}
Err(SourceError::NotFound)
}
}
impl<K> Debug for Registry<K> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("Registry")
.field("storages", &self.storages)
.finish()
}
}