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