1use std::hash::Hash;
8
9use json_ld_context_processing::Context;
10use json_ld_core::{Environment, ExpandedDocument, Loader, RemoteDocument};
11use json_syntax::Value;
12use rdf_types::{vocabulary, vocabulary::BlankIdVocabulary, BlankIdBuf, VocabularyMut};
13
14mod array;
15mod document;
16mod element;
17mod error;
18mod expanded;
19mod literal;
20mod node;
21mod options;
22mod value;
23mod warning;
24
25pub use error::*;
26pub use expanded::*;
27pub use options::*;
28pub use warning::*;
29
30pub(crate) use array::*;
31pub(crate) use document::filter_top_level_item;
32pub(crate) use element::*;
33pub(crate) use json_ld_context_processing::algorithm::expand_iri_simple as expand_iri;
34pub(crate) use literal::*;
35pub(crate) use node::*;
36pub(crate) use value::*;
37
38pub type ExpansionResult<T, B> = Result<ExpandedDocument<T, B>, Error>;
40
41pub trait WarningHandler<N: BlankIdVocabulary>:
44 json_ld_core::warning::Handler<N, Warning<N::BlankId>>
45{
46}
47
48impl<N: BlankIdVocabulary, H> WarningHandler<N> for H where
49 H: json_ld_core::warning::Handler<N, Warning<N::BlankId>>
50{
51}
52
53pub trait Expand<Iri> {
103 fn default_base_url(&self) -> Option<&Iri>;
107
108 #[allow(async_fn_in_trait)]
118 async fn expand_full<N, L, W>(
119 &self,
120 vocabulary: &mut N,
121 context: Context<Iri, N::BlankId>,
122 base_url: Option<&N::Iri>,
123 loader: &L,
124 options: Options,
125 warnings_handler: W,
126 ) -> ExpansionResult<N::Iri, N::BlankId>
127 where
128 N: VocabularyMut<Iri = Iri>,
129 Iri: Clone + Eq + Hash,
130 N::BlankId: Clone + Eq + Hash,
131 L: Loader,
132 W: WarningHandler<N>;
133
134 #[allow(async_fn_in_trait)]
142 async fn expand_with<'a, N, L>(
143 &'a self,
144 vocabulary: &'a mut N,
145 loader: &'a L,
146 ) -> ExpansionResult<Iri, N::BlankId>
147 where
148 N: VocabularyMut<Iri = Iri>,
149 Iri: 'a + Clone + Eq + Hash,
150 N::BlankId: 'a + Clone + Eq + Hash,
151 L: Loader,
152 {
153 self.expand_full(
154 vocabulary,
155 Context::<N::Iri, N::BlankId>::new(self.default_base_url().cloned()),
156 self.default_base_url(),
157 loader,
158 Options::default(),
159 (),
160 )
161 .await
162 }
163
164 #[allow(async_fn_in_trait)]
171 async fn expand<'a, L>(&'a self, loader: &'a L) -> ExpansionResult<Iri, BlankIdBuf>
172 where
173 (): VocabularyMut<Iri = Iri>,
174 Iri: 'a + Clone + Eq + Hash,
175 L: Loader,
176 {
177 self.expand_with(vocabulary::no_vocabulary_mut(), loader)
178 .await
179 }
180}
181
182impl<Iri> Expand<Iri> for Value {
184 fn default_base_url(&self) -> Option<&Iri> {
185 None
186 }
187
188 async fn expand_full<N, L, W>(
189 &self,
190 vocabulary: &mut N,
191 context: Context<Iri, N::BlankId>,
192 base_url: Option<&Iri>,
193 loader: &L,
194 options: Options,
195 mut warnings_handler: W,
196 ) -> ExpansionResult<Iri, N::BlankId>
197 where
198 N: VocabularyMut<Iri = Iri>,
199 Iri: Clone + Eq + Hash,
200 N::BlankId: Clone + Eq + Hash,
201 L: Loader,
202 W: WarningHandler<N>,
203 {
204 document::expand(
205 Environment {
206 vocabulary,
207 loader,
208 warnings: &mut warnings_handler,
209 },
210 self,
211 context,
212 base_url,
213 options,
214 )
215 .await
216 }
217}
218
219impl<Iri> Expand<Iri> for RemoteDocument<Iri> {
224 fn default_base_url(&self) -> Option<&Iri> {
225 self.url()
226 }
227
228 async fn expand_full<N, L, W>(
229 &self,
230 vocabulary: &mut N,
231 context: Context<Iri, N::BlankId>,
232 base_url: Option<&Iri>,
233 loader: &L,
234 options: Options,
235 warnings_handler: W,
236 ) -> ExpansionResult<Iri, N::BlankId>
237 where
238 N: VocabularyMut<Iri = Iri>,
239 Iri: Clone + Eq + Hash,
240 N::BlankId: Clone + Eq + Hash,
241 L: Loader,
242 W: WarningHandler<N>,
243 {
244 self.document()
245 .expand_full(
246 vocabulary,
247 context,
248 base_url,
249 loader,
250 options,
251 warnings_handler,
252 )
253 .await
254 }
255}