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, LinkedDataDeserializeSubject, LinkedDataResource,
10 LinkedDataSubject,
11};
12
13pub trait LinkedDataPredicateObjects<I: Interpretation = ()> {
15 fn visit_objects<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
17 where
18 S: PredicateObjectsVisitor<I>;
19}
20
21impl<I: Interpretation> LinkedDataPredicateObjects<I> for () {
22 fn visit_objects<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
23 where
24 S: PredicateObjectsVisitor<I>,
25 {
26 visitor.end()
27 }
28}
29
30impl<I: Interpretation, T: ?Sized + LinkedDataPredicateObjects<I>> LinkedDataPredicateObjects<I>
31 for &T
32{
33 fn visit_objects<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
34 where
35 S: PredicateObjectsVisitor<I>,
36 {
37 T::visit_objects(self, visitor)
38 }
39}
40
41impl<I: Interpretation, T: ?Sized + LinkedDataPredicateObjects<I>> LinkedDataPredicateObjects<I>
42 for Box<T>
43{
44 fn visit_objects<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
45 where
46 S: PredicateObjectsVisitor<I>,
47 {
48 T::visit_objects(self, visitor)
49 }
50}
51
52impl<I: Interpretation, T: LinkedDataSubject<I> + LinkedDataResource<I>>
53 LinkedDataPredicateObjects<I> for Option<T>
54{
55 fn visit_objects<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
56 where
57 S: PredicateObjectsVisitor<I>,
58 {
59 if let Some(t) = self {
60 visitor.object(t)?;
61 }
62 visitor.end()
63 }
64}
65
66impl<I: Interpretation, T: LinkedDataSubject<I> + LinkedDataResource<I>>
67 LinkedDataPredicateObjects<I> for [T]
68{
69 fn visit_objects<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
70 where
71 S: PredicateObjectsVisitor<I>,
72 {
73 for t in self {
74 visitor.object(t)?;
75 }
76 visitor.end()
77 }
78}
79
80impl<I: Interpretation, T: LinkedDataSubject<I> + LinkedDataResource<I>>
81 LinkedDataPredicateObjects<I> for Vec<T>
82{
83 fn visit_objects<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
84 where
85 S: PredicateObjectsVisitor<I>,
86 {
87 for t in self {
88 visitor.object(t)?;
89 }
90 visitor.end()
91 }
92}
93
94impl<I: Interpretation> LinkedDataPredicateObjects<I> for IriBuf {
95 fn visit_objects<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
96 where
97 S: PredicateObjectsVisitor<I>,
98 {
99 visitor.object(self)?;
100 visitor.end()
101 }
102}
103
104impl<I: Interpretation> LinkedDataPredicateObjects<I> for iri_rs::Iri<&str> {
105 fn visit_objects<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
106 where
107 S: PredicateObjectsVisitor<I>,
108 {
109 visitor.object(self)?;
110 visitor.end()
111 }
112}
113
114impl<I: Interpretation> LinkedDataPredicateObjects<I> for BlankId {
115 fn visit_objects<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
116 where
117 S: PredicateObjectsVisitor<I>,
118 {
119 visitor.object(self)?;
120 visitor.end()
121 }
122}
123
124impl<I: Interpretation> LinkedDataPredicateObjects<I> for BlankIdBuf {
125 fn visit_objects<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
126 where
127 S: PredicateObjectsVisitor<I>,
128 {
129 visitor.object(self)?;
130 visitor.end()
131 }
132}
133
134impl<I: Interpretation> LinkedDataPredicateObjects<I> for Id {
135 fn visit_objects<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
136 where
137 S: PredicateObjectsVisitor<I>,
138 {
139 visitor.object(self)?;
140 visitor.end()
141 }
142}
143
144pub trait PredicateObjectsVisitor<I: Interpretation> {
146 type Ok;
148 type Error;
150
151 fn object<T>(&mut self, value: &T) -> Result<(), Self::Error>
153 where
154 T: ?Sized + LinkedDataResource<I> + LinkedDataSubject<I>;
155
156 fn end(self) -> Result<Self::Ok, Self::Error>;
158}
159
160pub trait LinkedDataDeserializePredicateObjects<I: Interpretation>: Sized
162where
163 I::Resource: rdfx::Resource,
164{
165 fn deserialize_objects_in<'a, D>(
168 interpretation: &I,
169 dataset: &D,
170 graph: Option<&I::Resource>,
171 objects: impl IntoIterator<Item = &'a I::Resource>,
172 context: Context<I>,
173 ) -> Result<Self, FromLinkedDataError>
174 where
175 I::Resource: 'a,
176 D: PatternMatchingDataset<Subject = I::Resource>;
177
178 fn deserialize_objects<'a, D>(
180 interpretation: &I,
181 dataset: &D,
182 graph: Option<&I::Resource>,
183 objects: impl IntoIterator<Item = &'a I::Resource>,
184 ) -> Result<Self, FromLinkedDataError>
185 where
186 I::Resource: 'a,
187 D: PatternMatchingDataset<Subject = I::Resource>,
188 {
189 Self::deserialize_objects_in(interpretation, dataset, graph, objects, Context::default())
190 }
191}
192
193macro_rules! deserialize_single_object {
194 () => {
195 fn deserialize_objects_in<'a, D>(
196 interpretation: &I,
197 dataset: &D,
198 graph: Option<&I::Resource>,
199 objects: impl IntoIterator<Item = &'a I::Resource>,
200 context: $crate::Context<I>,
201 ) -> Result<Self, FromLinkedDataError>
202 where
203 I::Resource: 'a,
204 D: PatternMatchingDataset<Subject = I::Resource>,
205 {
206 use crate::LinkedDataDeserializeSubject;
207 let mut objects = objects.into_iter();
208 match objects.next() {
209 Some(object) => {
210 if objects.next().is_none() {
211 Self::deserialize_subject_in(
212 interpretation,
213 dataset,
214 graph,
215 object,
216 context,
217 )
218 } else {
219 Err(FromLinkedDataError::TooManyValues(
220 context.into_iris(interpretation),
221 ))
222 }
223 }
224 None => Err(FromLinkedDataError::MissingRequiredValue(
225 context.into_iris(interpretation),
226 )),
227 }
228 }
229 };
230}
231
232impl<I: Interpretation> LinkedDataDeserializePredicateObjects<I> for IriBuf
233where
234 I: ReverseInterpretation,
235 I::Resource: rdfx::Resource,
236{
237 deserialize_single_object!();
238}
239
240impl<I: Interpretation> LinkedDataDeserializePredicateObjects<I> for BlankIdBuf
241where
242 I: ReverseInterpretation + ReverseLocalInterpretation,
243 I::Resource: rdfx::Resource,
244{
245 deserialize_single_object!();
246}
247
248impl<I: Interpretation> LinkedDataDeserializePredicateObjects<I> for Id
249where
250 I: ReverseInterpretation + ReverseLocalInterpretation,
251 I::Resource: rdfx::Resource,
252{
253 deserialize_single_object!();
254}
255
256impl<I: Interpretation, T: LinkedDataDeserializePredicateObjects<I>>
257 LinkedDataDeserializePredicateObjects<I> for Box<T>
258where
259 I::Resource: rdfx::Resource,
260{
261 fn deserialize_objects_in<'a, D>(
262 interpretation: &I,
263 dataset: &D,
264 graph: Option<&I::Resource>,
265 objects: impl IntoIterator<Item = &'a I::Resource>,
266 context: Context<I>,
267 ) -> Result<Self, FromLinkedDataError>
268 where
269 I::Resource: 'a,
270 D: PatternMatchingDataset<Subject = I::Resource>,
271 {
272 T::deserialize_objects_in(interpretation, dataset, graph, objects, context).map(Box::new)
273 }
274}
275
276impl<I: Interpretation, T: LinkedDataDeserializeSubject<I>> LinkedDataDeserializePredicateObjects<I>
277 for Option<T>
278where
279 I: ReverseInterpretation,
280 I::Resource: rdfx::Resource,
281{
282 fn deserialize_objects_in<'a, D>(
283 interpretation: &I,
284 dataset: &D,
285 graph: Option<&I::Resource>,
286 objects: impl IntoIterator<Item = &'a I::Resource>,
287 context: Context<I>,
288 ) -> Result<Self, FromLinkedDataError>
289 where
290 I::Resource: 'a,
291 D: PatternMatchingDataset<Subject = I::Resource>,
292 {
293 let mut objects = objects.into_iter();
294 match objects.next() {
295 Some(object) => {
296 if objects.next().is_none() {
297 T::deserialize_subject_in(interpretation, dataset, graph, object, context)
298 .map(Some)
299 } else {
300 Err(FromLinkedDataError::TooManyValues(
301 context.into_iris(interpretation),
302 ))
303 }
304 }
305 None => Ok(None),
306 }
307 }
308}