linked_data_next/
predicate.rs

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