jsonld_core/loader/
chain.rs1use crate::LoadError;
2use iri_rs::{Iri, IriBuf};
3
4use super::{Loader, RemoteDocument};
5
6#[derive(Debug, Clone)]
15pub struct ChainLoader<L1, L2>(L1, L2);
16
17impl<L1, L2> ChainLoader<L1, L2> {
18 pub fn new(l1: L1, l2: L2) -> Self {
20 ChainLoader(l1, l2)
21 }
22}
23
24impl<L1, L2> Loader for ChainLoader<L1, L2>
25where
26 L1: Loader,
27 L2: Loader,
28{
29 type Error = ChainError<L1::Error, L2::Error>;
30
31 #[expect(
32 clippy::disallowed_methods,
33 reason = "a loader delegating to the loader it wraps already runs inside its caller's guarded poll"
34 )]
35 async fn load(&self, url: Iri<&str>) -> Result<RemoteDocument<IriBuf>, LoadError<Self::Error>> {
36 match self.0.load(url).await {
37 Ok(doc) => Ok(doc),
38 Err(LoadError { source: e1, .. }) => match self.1.load(url).await {
39 Ok(doc) => Ok(doc),
40 Err(LoadError { target, source: e2 }) => Err(LoadError::new(target, ChainError::Both(e1, e2))),
41 },
42 }
43 }
44}
45
46#[derive(Debug, thiserror::Error)]
51pub enum ChainError<A, B> {
52 #[error("both loaders failed: {0}, then {1}")]
54 Both(A, B),
55}