linked_data_next/
subject.rs

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
14/// Serialize a Linked-Data node.
15pub 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	/// Visit a predicate of the graph.
109	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	/// Visit a reverse predicate of the graph.
115	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}