1use iref::{Iri, IriBuf};
2use rdf_types::{
3 dataset::PatternMatchingDataset,
4 interpretation::{
5 ReverseBlankIdInterpretation, ReverseIdInterpretation, ReverseIriInterpretation,
6 },
7 vocabulary::{BlankIdVocabularyMut, IriVocabularyMut},
8 BlankId, BlankIdBuf, Id, Interpretation, Vocabulary,
9};
10
11use crate::{
12 Context, FromLinkedDataError, LinkedDataDeserializeSubject, LinkedDataResource,
13 LinkedDataSubject,
14};
15
16pub trait LinkedDataPredicateObjects<I: Interpretation = (), V: Vocabulary = ()> {
18 fn visit_objects<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
19 where
20 S: PredicateObjectsVisitor<I, V>;
21}
22
23impl<I: Interpretation, V: Vocabulary> LinkedDataPredicateObjects<I, V> for () {
24 fn visit_objects<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
25 where
26 S: PredicateObjectsVisitor<I, V>,
27 {
28 visitor.end()
29 }
30}
31
32impl<I: Interpretation, V: Vocabulary, T: ?Sized + LinkedDataPredicateObjects<I, V>>
33 LinkedDataPredicateObjects<I, V> for &T
34{
35 fn visit_objects<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
36 where
37 S: PredicateObjectsVisitor<I, V>,
38 {
39 T::visit_objects(self, visitor)
40 }
41}
42
43impl<I: Interpretation, V: Vocabulary, T: ?Sized + LinkedDataPredicateObjects<I, V>>
44 LinkedDataPredicateObjects<I, V> for Box<T>
45{
46 fn visit_objects<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
47 where
48 S: PredicateObjectsVisitor<I, V>,
49 {
50 T::visit_objects(self, visitor)
51 }
52}
53
54impl<I: Interpretation, V: Vocabulary, T: LinkedDataSubject<I, V> + LinkedDataResource<I, V>>
55 LinkedDataPredicateObjects<I, V> for Option<T>
56{
57 fn visit_objects<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
58 where
59 S: PredicateObjectsVisitor<I, V>,
60 {
61 if let Some(t) = self {
62 visitor.object(t)?;
63 }
64
65 visitor.end()
66 }
67}
68
69impl<I: Interpretation, V: Vocabulary, T: LinkedDataSubject<I, V> + LinkedDataResource<I, V>>
70 LinkedDataPredicateObjects<I, V> for [T]
71{
72 fn visit_objects<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
73 where
74 S: PredicateObjectsVisitor<I, V>,
75 {
76 for t in self {
77 visitor.object(t)?;
78 }
79
80 visitor.end()
81 }
82}
83
84impl<I: Interpretation, V: Vocabulary, T: LinkedDataSubject<I, V> + LinkedDataResource<I, V>>
85 LinkedDataPredicateObjects<I, V> for Vec<T>
86{
87 fn visit_objects<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
88 where
89 S: PredicateObjectsVisitor<I, V>,
90 {
91 for t in self {
92 visitor.object(t)?;
93 }
94
95 visitor.end()
96 }
97}
98
99impl<I: Interpretation, V: Vocabulary> LinkedDataPredicateObjects<I, V> for Iri
100where
101 V: IriVocabularyMut,
102{
103 fn visit_objects<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
104 where
105 S: PredicateObjectsVisitor<I, V>,
106 {
107 visitor.object(self)?;
108 visitor.end()
109 }
110}
111
112impl<I: Interpretation, V: Vocabulary> LinkedDataPredicateObjects<I, V> for IriBuf
113where
114 V: IriVocabularyMut,
115{
116 fn visit_objects<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
117 where
118 S: PredicateObjectsVisitor<I, V>,
119 {
120 visitor.object(self)?;
121 visitor.end()
122 }
123}
124
125impl<I: Interpretation, V: Vocabulary> LinkedDataPredicateObjects<I, V> for BlankId
126where
127 V: BlankIdVocabularyMut,
128{
129 fn visit_objects<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
130 where
131 S: PredicateObjectsVisitor<I, V>,
132 {
133 visitor.object(self)?;
134 visitor.end()
135 }
136}
137
138impl<I: Interpretation, V: Vocabulary> LinkedDataPredicateObjects<I, V> for BlankIdBuf
139where
140 V: BlankIdVocabularyMut,
141{
142 fn visit_objects<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
143 where
144 S: PredicateObjectsVisitor<I, V>,
145 {
146 visitor.object(self)?;
147 visitor.end()
148 }
149}
150
151impl<I: Interpretation, V: Vocabulary, T, B> LinkedDataPredicateObjects<I, V> for Id<T, B>
152where
153 T: LinkedDataPredicateObjects<I, V>,
154 B: LinkedDataPredicateObjects<I, V>,
155{
156 fn visit_objects<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
157 where
158 S: PredicateObjectsVisitor<I, V>,
159 {
160 match self {
161 Self::Iri(i) => i.visit_objects(visitor),
162 Self::Blank(b) => b.visit_objects(visitor),
163 }
164 }
165}
166
167pub trait PredicateObjectsVisitor<I: Interpretation, V: Vocabulary> {
168 type Ok;
169 type Error;
170
171 fn object<T>(&mut self, value: &T) -> Result<(), Self::Error>
172 where
173 T: ?Sized + LinkedDataResource<I, V> + LinkedDataSubject<I, V>;
174
175 fn end(self) -> Result<Self::Ok, Self::Error>;
176}
177
178pub trait LinkedDataDeserializePredicateObjects<I: Interpretation = (), V: Vocabulary = ()>:
179 Sized
180{
181 fn deserialize_objects_in<'a, D>(
182 vocabulary: &V,
183 interpretation: &I,
184 dataset: &D,
185 graph: Option<&I::Resource>,
186 objects: impl IntoIterator<Item = &'a I::Resource>,
187 context: Context<I>,
188 ) -> Result<Self, FromLinkedDataError>
189 where
190 I::Resource: 'a,
191 D: PatternMatchingDataset<Resource = I::Resource>;
192
193 fn deserialize_objects<'a, D>(
194 vocabulary: &V,
195 interpretation: &I,
196 dataset: &D,
197 graph: Option<&I::Resource>,
198 objects: impl IntoIterator<Item = &'a I::Resource>,
199 ) -> Result<Self, FromLinkedDataError>
200 where
201 I::Resource: 'a,
202 D: PatternMatchingDataset<Resource = I::Resource>,
203 {
204 Self::deserialize_objects_in(
205 vocabulary,
206 interpretation,
207 dataset,
208 graph,
209 objects,
210 Context::default(),
211 )
212 }
213}
214
215macro_rules! deserialize_single_object {
216 () => {
217 fn deserialize_objects_in<'a, D>(
218 vocabulary: &V,
219 interpretation: &I,
220 dataset: &D,
221 graph: Option<&I::Resource>,
222 objects: impl IntoIterator<Item = &'a I::Resource>,
223 context: $crate::Context<I>,
224 ) -> Result<Self, FromLinkedDataError>
225 where
226 I::Resource: 'a,
227 D: PatternMatchingDataset<Resource = I::Resource>,
228 {
229 use crate::LinkedDataDeserializeSubject;
230 let mut objects = objects.into_iter();
231 match objects.next() {
232 Some(object) => {
233 if objects.next().is_none() {
234 Self::deserialize_subject_in(
235 vocabulary,
236 interpretation,
237 dataset,
238 graph,
239 object,
240 context,
241 )
242 } else {
243 Err(FromLinkedDataError::TooManyValues(
244 context.into_iris(vocabulary, interpretation),
245 ))
246 }
247 }
248 None => Err(FromLinkedDataError::MissingRequiredValue(
249 context.into_iris(vocabulary, interpretation),
250 )),
251 }
252 }
253 };
254}
255
256impl<I: Interpretation, V: Vocabulary> LinkedDataDeserializePredicateObjects<I, V> for IriBuf
257where
258 I: ReverseIriInterpretation<Iri = V::Iri>,
259{
260 deserialize_single_object!();
261}
262
263impl<I: Interpretation, V: Vocabulary> LinkedDataDeserializePredicateObjects<I, V> for BlankIdBuf
264where
265 I: ReverseIriInterpretation<Iri = V::Iri> + ReverseBlankIdInterpretation<BlankId = V::BlankId>,
266{
267 deserialize_single_object!();
268}
269
270impl<I: Interpretation, V: Vocabulary> LinkedDataDeserializePredicateObjects<I, V> for Id
271where
272 I: ReverseIdInterpretation<Iri = V::Iri, BlankId = V::BlankId>,
273{
274 deserialize_single_object!();
275}
276
277impl<I: Interpretation, V: Vocabulary, T: LinkedDataDeserializePredicateObjects<I, V>>
278 LinkedDataDeserializePredicateObjects<I, V> for Box<T>
279{
280 fn deserialize_objects_in<'a, D>(
281 vocabulary: &V,
282 interpretation: &I,
283 dataset: &D,
284 graph: Option<&I::Resource>,
285 objects: impl IntoIterator<Item = &'a I::Resource>,
286 context: Context<I>,
287 ) -> Result<Self, FromLinkedDataError>
288 where
289 I::Resource: 'a,
290 D: PatternMatchingDataset<Resource = I::Resource>,
291 {
292 T::deserialize_objects_in(vocabulary, interpretation, dataset, graph, objects, context)
293 .map(Box::new)
294 }
295}
296
297impl<I: Interpretation, V: Vocabulary, T: LinkedDataDeserializeSubject<I, V>>
298 LinkedDataDeserializePredicateObjects<I, V> for Option<T>
299where
300 I: ReverseIriInterpretation<Iri = V::Iri>,
301{
302 fn deserialize_objects_in<'a, D>(
303 vocabulary: &V,
304 interpretation: &I,
305 dataset: &D,
306 graph: Option<&I::Resource>,
307 objects: impl IntoIterator<Item = &'a I::Resource>,
308 context: Context<I>,
309 ) -> Result<Self, FromLinkedDataError>
310 where
311 I::Resource: 'a,
312 D: PatternMatchingDataset<Resource = I::Resource>,
313 {
314 let mut objects = objects.into_iter();
315 match objects.next() {
316 Some(object) => {
317 if objects.next().is_none() {
318 T::deserialize_subject_in(
319 vocabulary,
320 interpretation,
321 dataset,
322 graph,
323 object,
324 context,
325 )
326 .map(Some)
327 } else {
328 Err(FromLinkedDataError::TooManyValues(
329 context.into_iris(vocabulary, interpretation),
330 ))
331 }
332 }
333 None => Ok(None),
334 }
335 }
336}
337
338impl<I: Interpretation, V: Vocabulary, T: LinkedDataDeserializeSubject<I, V>>
339 LinkedDataDeserializePredicateObjects<I, V> for Vec<T>
340where
341 I: ReverseIriInterpretation<Iri = V::Iri>,
342{
343 fn deserialize_objects_in<'a, D>(
344 vocabulary: &V,
345 interpretation: &I,
346 dataset: &D,
347 graph: Option<&I::Resource>,
348 objects: impl IntoIterator<Item = &'a I::Resource>,
349 context: Context<I>,
350 ) -> Result<Self, FromLinkedDataError>
351 where
352 I::Resource: 'a,
353 D: PatternMatchingDataset<Resource = I::Resource>,
354 {
355 objects
356 .into_iter()
357 .map(|object| {
358 T::deserialize_subject_in(
359 vocabulary,
360 interpretation,
361 dataset,
362 graph,
363 object,
364 context,
365 )
366 })
367 .collect::<Result<Vec<_>, _>>()
368 }
369}