json_ld/processor/
remote_document.rs

1use super::{
2	compact_expanded_full, CompactError, CompactResult, CompareResult, ExpandError, ExpandResult,
3	FlattenError, FlattenResult, JsonLdProcessor, Options,
4};
5use crate::context_processing::{self, Process};
6use crate::expansion::{self, Expand};
7use crate::IntoDocumentResult;
8use crate::{Context, Flatten, Loader, RemoteDocument, RemoteDocumentReference};
9use contextual::WithContext;
10use json_ld_core::{Document, RemoteContextReference};
11use rdf_types::{Generator, VocabularyMut};
12use std::hash::Hash;
13
14impl<I> JsonLdProcessor<I> for RemoteDocument<I> {
15	async fn compare_full<N>(
16		&self,
17		other: &Self,
18		vocabulary: &mut N,
19		loader: &impl Loader,
20		options: Options<I>,
21		mut warnings: impl context_processing::WarningHandler<N> + expansion::WarningHandler<N>,
22	) -> CompareResult
23	where
24		N: VocabularyMut<Iri = I>,
25		I: Clone + Eq + Hash,
26		N::BlankId: Clone + Eq + Hash,
27	{
28		if json_ld_syntax::Compare::compare(self.document(), other.document()) {
29			let a = JsonLdProcessor::expand_full(
30				self,
31				vocabulary,
32				loader,
33				options.clone(),
34				&mut warnings,
35			)
36			.await?;
37			let b = JsonLdProcessor::expand_full(other, vocabulary, loader, options, &mut warnings)
38				.await?;
39			Ok(a == b)
40		} else {
41			Ok(false)
42		}
43	}
44
45	async fn expand_full<N>(
46		&self,
47		vocabulary: &mut N,
48		loader: &impl Loader,
49		mut options: Options<I>,
50		mut warnings: impl context_processing::WarningHandler<N> + expansion::WarningHandler<N>,
51	) -> ExpandResult<I, N::BlankId>
52	where
53		N: VocabularyMut<Iri = I>,
54		I: Clone + Eq + Hash,
55		N::BlankId: Clone + Eq + Hash,
56	{
57		let mut active_context = Context::new(options.base.clone().or_else(|| self.url().cloned()));
58
59		if let Some(expand_context) = options.expand_context.take() {
60			active_context = expand_context
61				.load_context_with(vocabulary, loader)
62				.await
63				.map_err(ExpandError::ContextLoading)?
64				.into_document()
65				.process_full(
66					vocabulary,
67					&active_context,
68					loader,
69					active_context.original_base_url().cloned(),
70					options.context_processing_options(),
71					&mut warnings,
72				)
73				.await
74				.map_err(ExpandError::ContextProcessing)?
75				.into_processed()
76		};
77
78		if let Some(context_url) = self.context_url() {
79			active_context = RemoteDocumentReference::Iri(context_url.clone())
80				.load_context_with(vocabulary, loader)
81				.await
82				.map_err(ExpandError::ContextLoading)?
83				.into_document()
84				.process_full(
85					vocabulary,
86					&active_context,
87					loader,
88					Some(context_url.clone()),
89					options.context_processing_options(),
90					&mut warnings,
91				)
92				.await
93				.map_err(ExpandError::ContextProcessing)?
94				.into_processed()
95		}
96
97		self.document()
98			.expand_full(
99				vocabulary,
100				active_context,
101				self.url().or(options.base.as_ref()),
102				loader,
103				options.expansion_options(),
104				warnings,
105			)
106			.await
107			.map_err(ExpandError::Expansion)
108	}
109
110	async fn into_document_full<'a, N>(
111		self,
112		vocabulary: &'a mut N,
113		loader: &'a impl Loader,
114		options: Options<I>,
115		warnings: impl 'a + context_processing::WarningHandler<N> + expansion::WarningHandler<N>,
116	) -> IntoDocumentResult<I, N::BlankId>
117	where
118		N: VocabularyMut<Iri = I>,
119		I: 'a + Clone + Eq + Hash,
120		N::BlankId: 'a + Clone + Eq + Hash,
121	{
122		let expanded =
123			JsonLdProcessor::expand_full(&self, vocabulary, loader, options, warnings).await?;
124		Ok(Document::new(self, expanded))
125	}
126
127	async fn compact_full<'a, N>(
128		&'a self,
129		vocabulary: &'a mut N,
130		context: RemoteContextReference<I>,
131		loader: &'a impl Loader,
132		options: Options<I>,
133		mut warnings: impl 'a + context_processing::WarningHandler<N> + expansion::WarningHandler<N>,
134	) -> CompactResult
135	where
136		N: VocabularyMut<Iri = I>,
137		I: Clone + Eq + Hash,
138		N::BlankId: 'a + Clone + Eq + Hash,
139	{
140		let expanded_input = JsonLdProcessor::expand_full(
141			self,
142			vocabulary,
143			loader,
144			options.clone().unordered(),
145			&mut warnings,
146		)
147		.await
148		.map_err(CompactError::Expand)?;
149
150		compact_expanded_full(
151			&expanded_input,
152			self.url(),
153			vocabulary,
154			context,
155			loader,
156			options,
157			warnings,
158		)
159		.await
160	}
161
162	async fn flatten_full<'a, N>(
163		&'a self,
164		vocabulary: &'a mut N,
165		generator: &'a mut impl Generator<N>,
166		context: Option<RemoteContextReference<I>>,
167		loader: &'a impl Loader,
168		options: Options<I>,
169		mut warnings: impl 'a + context_processing::WarningHandler<N> + expansion::WarningHandler<N>,
170	) -> FlattenResult<I, N::BlankId>
171	where
172		N: VocabularyMut<Iri = I>,
173		I: Clone + Eq + Hash,
174		N::BlankId: 'a + Clone + Eq + Hash,
175	{
176		let expanded_input = JsonLdProcessor::expand_full(
177			self,
178			vocabulary,
179			loader,
180			options.clone().unordered(),
181			&mut warnings,
182		)
183		.await
184		.map_err(FlattenError::Expand)?;
185
186		let flattened_output =
187			Flatten::flatten_with(expanded_input, vocabulary, generator, options.ordered)
188				.map_err(FlattenError::ConflictingIndexes)?;
189
190		match context {
191			Some(context) => compact_expanded_full(
192				&flattened_output,
193				self.url(),
194				vocabulary,
195				context,
196				loader,
197				options,
198				warnings,
199			)
200			.await
201			.map_err(FlattenError::Compact),
202			None => Ok(json_ld_syntax::IntoJson::into_json(
203				flattened_output.into_with(vocabulary),
204			)),
205		}
206	}
207}
208
209impl<I> JsonLdProcessor<I> for RemoteDocumentReference<I, json_syntax::Value> {
210	async fn compare_full<N>(
211		&self,
212		other: &Self,
213		vocabulary: &mut N,
214		loader: &impl Loader,
215		options: Options<I>,
216		warnings: impl context_processing::WarningHandler<N> + expansion::WarningHandler<N>,
217	) -> CompareResult
218	where
219		N: VocabularyMut<Iri = I>,
220		I: Clone + Eq + Hash,
221		N::BlankId: Clone + Eq + Hash,
222	{
223		let a = self.loaded_with(vocabulary, loader).await?;
224		let b = other.loaded_with(vocabulary, loader).await?;
225		JsonLdProcessor::compare_full(
226			a.as_ref(),
227			b.as_ref(),
228			vocabulary,
229			loader,
230			options,
231			warnings,
232		)
233		.await
234	}
235
236	async fn expand_full<N>(
237		&self,
238		vocabulary: &mut N,
239		loader: &impl Loader,
240		options: Options<I>,
241		warnings: impl context_processing::WarningHandler<N> + expansion::WarningHandler<N>,
242	) -> ExpandResult<I, N::BlankId>
243	where
244		N: VocabularyMut<Iri = I>,
245		I: Clone + Eq + Hash,
246		N::BlankId: Clone + Eq + Hash,
247	{
248		let doc = self.loaded_with(vocabulary, loader).await?;
249		JsonLdProcessor::expand_full(doc.as_ref(), vocabulary, loader, options, warnings).await
250	}
251
252	async fn into_document_full<'a, N>(
253		self,
254		vocabulary: &'a mut N,
255		loader: &'a impl Loader,
256		options: Options<I>,
257		warnings: impl 'a + context_processing::WarningHandler<N> + expansion::WarningHandler<N>,
258	) -> IntoDocumentResult<I, N::BlankId>
259	where
260		N: VocabularyMut<Iri = I>,
261		I: 'a + Clone + Eq + Hash,
262		N::BlankId: 'a + Clone + Eq + Hash,
263	{
264		let doc = self.load_with(vocabulary, loader).await?;
265		JsonLdProcessor::into_document_full(doc, vocabulary, loader, options, warnings).await
266	}
267
268	async fn compact_full<'a, N>(
269		&'a self,
270		vocabulary: &'a mut N,
271		context: RemoteContextReference<I>,
272		loader: &'a impl Loader,
273		options: Options<I>,
274		warnings: impl 'a + context_processing::WarningHandler<N> + expansion::WarningHandler<N>,
275	) -> CompactResult
276	where
277		N: VocabularyMut<Iri = I>,
278		I: Clone + Eq + Hash,
279		N::BlankId: 'a + Clone + Eq + Hash,
280	{
281		let doc = self.loaded_with(vocabulary, loader).await?;
282		JsonLdProcessor::compact_full(doc.as_ref(), vocabulary, context, loader, options, warnings)
283			.await
284	}
285
286	async fn flatten_full<'a, N>(
287		&'a self,
288		vocabulary: &'a mut N,
289		generator: &'a mut impl Generator<N>,
290		context: Option<RemoteContextReference<I>>,
291		loader: &'a impl Loader,
292		options: Options<I>,
293		warnings: impl 'a + context_processing::WarningHandler<N> + expansion::WarningHandler<N>,
294	) -> FlattenResult<I, N::BlankId>
295	where
296		N: VocabularyMut<Iri = I>,
297		I: Clone + Eq + Hash,
298		N::BlankId: 'a + Clone + Eq + Hash,
299	{
300		let doc = self.loaded_with(vocabulary, loader).await?;
301		JsonLdProcessor::flatten_full(
302			doc.as_ref(),
303			vocabulary,
304			generator,
305			context,
306			loader,
307			options,
308			warnings,
309		)
310		.await
311	}
312}