use crate::LoadError;
use iri_rs::{Iri, IriBuf};
use super::{Loader, RemoteDocument};
#[derive(Debug, Clone)]
pub struct ChainLoader<L1, L2>(L1, L2);
impl<L1, L2> ChainLoader<L1, L2> {
pub fn new(l1: L1, l2: L2) -> Self {
ChainLoader(l1, l2)
}
}
impl<L1, L2> Loader for ChainLoader<L1, L2>
where
L1: Loader,
L2: Loader,
{
type Error = ChainError<L1::Error, L2::Error>;
async fn load(&self, url: Iri<&str>) -> Result<RemoteDocument<IriBuf>, LoadError<Self::Error>> {
match self.0.load(url).await {
Ok(doc) => Ok(doc),
Err(LoadError { source: e1, .. }) => match self.1.load(url).await {
Ok(doc) => Ok(doc),
Err(LoadError { target, source: e2 }) => Err(LoadError::new(target, ChainError::Both(e1, e2))),
},
}
}
}
#[derive(Debug, thiserror::Error)]
pub enum ChainError<A, B> {
#[error("both loaders failed: {0}, then {1}")]
Both(A, B),
}