1use iri_rs::IriBuf;
2use rdfx::{
3 BlankId, BlankIdBuf, Id, Interpretation,
4 dataset::PatternMatchingDataset,
5 interpretation::{ReverseInterpretation, ReverseLocalInterpretation},
6};
7
8use crate::{
9 Context, FromLinkedDataError, LinkedDataGraph, LinkedDataPredicateObjects, LinkedDataResource,
10};
11
12pub trait LinkedDataSubject<I: Interpretation = ()> {
14 fn visit_subject<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
16 where
17 S: SubjectVisitor<I>;
18}
19
20impl<I: Interpretation> LinkedDataSubject<I> for () {
21 fn visit_subject<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
22 where
23 S: SubjectVisitor<I>,
24 {
25 serializer.end()
26 }
27}
28
29impl<I: Interpretation, T: ?Sized + LinkedDataSubject<I>> LinkedDataSubject<I> for &T {
30 fn visit_subject<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
31 where
32 S: SubjectVisitor<I>,
33 {
34 T::visit_subject(self, serializer)
35 }
36}
37
38impl<I: Interpretation, T: ?Sized + LinkedDataSubject<I>> LinkedDataSubject<I> for Box<T> {
39 fn visit_subject<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
40 where
41 S: SubjectVisitor<I>,
42 {
43 T::visit_subject(self, serializer)
44 }
45}
46
47impl<I: Interpretation> LinkedDataSubject<I> for IriBuf {
48 fn visit_subject<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
49 where
50 S: SubjectVisitor<I>,
51 {
52 serializer.end()
53 }
54}
55
56impl<I: Interpretation> LinkedDataSubject<I> for iri_rs::Iri<&str> {
57 fn visit_subject<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
58 where
59 S: SubjectVisitor<I>,
60 {
61 serializer.end()
62 }
63}
64
65impl<I: Interpretation> LinkedDataSubject<I> for BlankId {
66 fn visit_subject<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
67 where
68 S: SubjectVisitor<I>,
69 {
70 serializer.end()
71 }
72}
73
74impl<I: Interpretation> LinkedDataSubject<I> for BlankIdBuf {
75 fn visit_subject<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
76 where
77 S: SubjectVisitor<I>,
78 {
79 serializer.end()
80 }
81}
82
83impl<I: Interpretation> LinkedDataSubject<I> for Id {
84 fn visit_subject<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
85 where
86 S: SubjectVisitor<I>,
87 {
88 serializer.end()
89 }
90}
91
92pub trait SubjectVisitor<I: Interpretation> {
94 type Ok;
96 type Error;
98
99 fn predicate<L, T>(&mut self, predicate: &L, objects: &T) -> Result<(), Self::Error>
101 where
102 L: ?Sized + LinkedDataResource<I>,
103 T: ?Sized + LinkedDataPredicateObjects<I>;
104
105 fn reverse_predicate<L, T>(&mut self, predicate: &L, subjects: &T) -> Result<(), Self::Error>
107 where
108 L: ?Sized + LinkedDataResource<I>,
109 T: ?Sized + LinkedDataPredicateObjects<I>;
110
111 fn graph<T>(&mut self, value: &T) -> Result<(), Self::Error>
113 where
114 T: ?Sized + LinkedDataGraph<I>;
115
116 fn include<T>(&mut self, value: &T) -> Result<(), Self::Error>
118 where
119 T: ?Sized + LinkedDataResource<I> + LinkedDataSubject<I>;
120
121 fn end(self) -> Result<Self::Ok, Self::Error>;
123}
124
125impl<I: Interpretation, S: SubjectVisitor<I>> SubjectVisitor<I> for &mut S {
126 type Ok = ();
127 type Error = S::Error;
128
129 fn predicate<L, T>(&mut self, predicate: &L, objects: &T) -> Result<(), Self::Error>
130 where
131 L: ?Sized + LinkedDataResource<I>,
132 T: ?Sized + LinkedDataPredicateObjects<I>,
133 {
134 S::predicate(self, predicate, objects)
135 }
136
137 fn reverse_predicate<L, T>(&mut self, predicate: &L, subjects: &T) -> Result<(), Self::Error>
138 where
139 L: ?Sized + LinkedDataResource<I>,
140 T: ?Sized + LinkedDataPredicateObjects<I>,
141 {
142 S::reverse_predicate(self, predicate, subjects)
143 }
144
145 fn graph<T>(&mut self, value: &T) -> Result<(), Self::Error>
146 where
147 T: ?Sized + LinkedDataGraph<I>,
148 {
149 S::graph(self, value)
150 }
151
152 fn include<T>(&mut self, value: &T) -> Result<(), Self::Error>
153 where
154 T: ?Sized + LinkedDataResource<I> + LinkedDataSubject<I>,
155 {
156 S::include(self, value)
157 }
158
159 fn end(self) -> Result<Self::Ok, Self::Error> {
160 Ok(())
161 }
162}
163
164pub trait LinkedDataDeserializeSubject<I: Interpretation>: Sized
166where
167 I::Resource: rdfx::Resource,
168{
169 fn deserialize_subject_in<D>(
172 interpretation: &I,
173 dataset: &D,
174 graph: Option<&I::Resource>,
175 resource: &I::Resource,
176 context: Context<I>,
177 ) -> Result<Self, FromLinkedDataError>
178 where
179 D: PatternMatchingDataset<Subject = I::Resource>;
180
181 fn deserialize_subject<D>(
183 interpretation: &I,
184 dataset: &D,
185 graph: Option<&I::Resource>,
186 resource: &I::Resource,
187 ) -> Result<Self, FromLinkedDataError>
188 where
189 D: PatternMatchingDataset<Subject = I::Resource>,
190 {
191 Self::deserialize_subject_in(interpretation, dataset, graph, resource, Context::default())
192 }
193}
194
195impl<I: Interpretation> LinkedDataDeserializeSubject<I> for IriBuf
196where
197 I: ReverseInterpretation,
198 I::Resource: rdfx::Resource,
199{
200 fn deserialize_subject_in<D>(
201 interpretation: &I,
202 _dataset: &D,
203 _graph: Option<&I::Resource>,
204 resource: &I::Resource,
205 context: Context<I>,
206 ) -> Result<Self, FromLinkedDataError>
207 where
208 D: PatternMatchingDataset<Subject = I::Resource>,
209 {
210 match interpretation.iris_of(resource).next() {
211 Some(i) => Ok(i.into_owned()),
212 None => Err(FromLinkedDataError::InvalidSubject {
213 context: context.into_iris(interpretation),
214 subject: None,
215 }),
216 }
217 }
218}
219
220impl<I: Interpretation> LinkedDataDeserializeSubject<I> for BlankIdBuf
221where
222 I: ReverseInterpretation + ReverseLocalInterpretation,
223 I::Resource: rdfx::Resource,
224{
225 fn deserialize_subject_in<D>(
226 interpretation: &I,
227 _dataset: &D,
228 _graph: Option<&I::Resource>,
229 resource: &I::Resource,
230 context: Context<I>,
231 ) -> Result<Self, FromLinkedDataError>
232 where
233 D: PatternMatchingDataset<Subject = I::Resource>,
234 {
235 match interpretation.blank_ids_of(resource).next() {
236 Some(b) => Ok(b.into_owned()),
237 None => Err(FromLinkedDataError::InvalidSubject {
238 context: context.into_iris(interpretation),
239 subject: interpretation
240 .iris_of(resource)
241 .next()
242 .map(|i| i.into_owned()),
243 }),
244 }
245 }
246}
247
248impl<I: Interpretation> LinkedDataDeserializeSubject<I> for Id
249where
250 I: ReverseInterpretation + ReverseLocalInterpretation,
251 I::Resource: rdfx::Resource,
252{
253 fn deserialize_subject_in<D>(
254 interpretation: &I,
255 _dataset: &D,
256 _graph: Option<&I::Resource>,
257 resource: &I::Resource,
258 context: Context<I>,
259 ) -> Result<Self, FromLinkedDataError>
260 where
261 D: PatternMatchingDataset<Subject = I::Resource>,
262 {
263 if let Some(i) = interpretation.iris_of(resource).next() {
264 return Ok(Id::Iri(i.into_owned()));
265 }
266 if let Some(b) = interpretation.blank_ids_of(resource).next() {
267 return Ok(Id::BlankId(b.into_owned()));
268 }
269 Err(FromLinkedDataError::InvalidSubject {
270 context: context.into_iris(interpretation),
271 subject: None,
272 })
273 }
274}
275
276impl<I: Interpretation, T: LinkedDataDeserializeSubject<I>> LinkedDataDeserializeSubject<I>
277 for Box<T>
278where
279 I::Resource: rdfx::Resource,
280{
281 fn deserialize_subject_in<D>(
282 interpretation: &I,
283 dataset: &D,
284 graph: Option<&I::Resource>,
285 resource: &I::Resource,
286 context: Context<I>,
287 ) -> Result<Self, FromLinkedDataError>
288 where
289 D: PatternMatchingDataset<Subject = I::Resource>,
290 {
291 T::deserialize_subject_in(interpretation, dataset, graph, resource, context).map(Box::new)
292 }
293}