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}