linked_data/
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<'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	/// 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<'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}