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<'a, I: Interpretation, V: Vocabulary, T: ?Sized + LinkedDataSubject<I, V>>
31 LinkedDataSubject<I, V> for &'a 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<'s, I: Interpretation, V: Vocabulary, S: SubjectVisitor<I, V>> SubjectVisitor<I, V>
132 for &'s mut S
133{
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
205impl<I: Interpretation, V: Vocabulary> LinkedDataDeserializeSubject<I, V> for IriBuf
206where
207 I: ReverseIriInterpretation<Iri = V::Iri>,
208{
209 fn deserialize_subject_in<D>(
210 vocabulary: &V,
211 interpretation: &I,
212 _dataset: &D,
213 _graph: Option<&I::Resource>,
214 resource: &I::Resource,
215 context: Context<I>,
216 ) -> Result<Self, FromLinkedDataError>
217 where
218 D: PatternMatchingDataset<Resource = I::Resource>,
219 {
220 match interpretation.iris_of(resource).next() {
221 Some(i) => {
222 let iri = vocabulary.iri(i).unwrap();
223 Ok(iri.to_owned())
224 }
225 None => Err(FromLinkedDataError::InvalidSubject {
226 context: context.into_iris(vocabulary, interpretation),
227 subject: None,
228 }),
229 }
230 }
231}
232
233impl<I: Interpretation, V: Vocabulary> LinkedDataDeserializeSubject<I, V> for BlankIdBuf
234where
235 I: ReverseIriInterpretation<Iri = V::Iri> + ReverseBlankIdInterpretation<BlankId = V::BlankId>,
236{
237 fn deserialize_subject_in<D>(
238 vocabulary: &V,
239 interpretation: &I,
240 _dataset: &D,
241 _graph: Option<&I::Resource>,
242 resource: &I::Resource,
243 context: Context<I>,
244 ) -> Result<Self, FromLinkedDataError>
245 where
246 D: PatternMatchingDataset<Resource = I::Resource>,
247 {
248 match interpretation.blank_ids_of(resource).next() {
249 Some(b) => {
250 let blank_id = vocabulary.blank_id(b).unwrap();
251 Ok(blank_id.to_owned())
252 }
253 None => Err(FromLinkedDataError::InvalidSubject {
254 context: context.into_iris(vocabulary, interpretation),
255 subject: interpretation
256 .iris_of(resource)
257 .next()
258 .map(|i| vocabulary.iri(i).unwrap().to_owned()),
259 }),
260 }
261 }
262}
263
264impl<I: Interpretation, V: Vocabulary> LinkedDataDeserializeSubject<I, V> for Id
265where
266 I: ReverseIdInterpretation<Iri = V::Iri, BlankId = V::BlankId>,
267{
268 fn deserialize_subject_in<D>(
269 vocabulary: &V,
270 interpretation: &I,
271 _dataset: &D,
272 _graph: Option<&I::Resource>,
273 resource: &I::Resource,
274 context: Context<I>,
275 ) -> Result<Self, FromLinkedDataError>
276 where
277 D: PatternMatchingDataset<Resource = I::Resource>,
278 {
279 match interpretation.ids_of(resource).next() {
280 Some(Id::Iri(i)) => {
281 let iri = vocabulary.iri(i).unwrap();
282 Ok(Id::Iri(iri.to_owned()))
283 }
284 Some(Id::Blank(b)) => {
285 let blank_id = vocabulary.blank_id(b).unwrap();
286 Ok(Id::Blank(blank_id.to_owned()))
287 }
288 None => Err(FromLinkedDataError::InvalidSubject {
289 context: context.into_iris(vocabulary, interpretation),
290 subject: None,
291 }),
292 }
293 }
294}
295
296impl<I: Interpretation, V: Vocabulary, T: LinkedDataDeserializeSubject<I, V>>
297 LinkedDataDeserializeSubject<I, V> for Box<T>
298{
299 fn deserialize_subject_in<D>(
300 vocabulary: &V,
301 interpretation: &I,
302 dataset: &D,
303 graph: Option<&I::Resource>,
304 resource: &I::Resource,
305 context: Context<I>,
306 ) -> Result<Self, FromLinkedDataError>
307 where
308 D: PatternMatchingDataset<Resource = I::Resource>,
309 {
310 T::deserialize_subject_in(
311 vocabulary,
312 interpretation,
313 dataset,
314 graph,
315 resource,
316 context,
317 )
318 .map(Box::new)
319 }
320}