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