sophia_jsonld/loader/
chain_loader.rs1use std::fmt::Debug;
2
3use json_ld::future::{BoxFuture, FutureExt};
4use json_ld::Loader;
5use json_syntax::Value;
6use locspan::Location;
7
8#[derive(Clone, Debug, Default)]
10pub struct ChainLoader<L1, L2>(L1, L2);
11
12impl<L1, L2> ChainLoader<L1, L2> {
13 pub const fn new(l1: L1, l2: L2) -> Self {
15 Self(l1, l2)
16 }
17}
18
19impl<I, L1, L2> Loader<I, Location<I>> for ChainLoader<L1, L2>
20where
21 I: Clone + Send + Sync,
22 L1: Loader<I, Location<I>, Output = Value<Location<I>>> + Send,
23 L2: Loader<I, Location<I>, Output = Value<Location<I>>> + Send,
24 L1::Error: Debug + Send,
25 L2::Error: Debug,
26{
27 type Output = Value<Location<I>>;
28
29 type Error = ChainLoaderError<L1::Error, L2::Error>;
30
31 fn load_with<'a>(
32 &'a mut self,
33 vocabulary: &'a mut (impl Sync + Send + rdf_types::IriVocabularyMut<Iri = I>),
34 url: I,
35 ) -> BoxFuture<'a, json_ld::LoadingResult<I, Location<I>, Self::Output, Self::Error>>
36 where
37 I: 'a,
38 {
39 async {
40 match self.0.load_with(vocabulary, url.clone()).await {
41 Ok(doc) => Ok(doc),
42 Err(err1) => match self.1.load_with(vocabulary, url).await {
43 Ok(doc) => Ok(doc),
44 Err(err2) => Err(ChainLoaderError(err1, err2)),
45 },
46 }
47 }
48 .boxed()
49 }
50}
51
52#[derive(thiserror::Error, Debug)]
54#[error("Document not found {0}")]
55pub struct ChainLoaderError<E1, E2>(E1, E2)
56where
57 E1: Debug,
58 E2: Debug;