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