linked_data_next/
quads.rs

1use educe::Educe;
2use iref::IriBuf;
3use rdf_types::{
4	interpretation::{
5		self, BlankIdInterpretationMut, IriInterpretationMut, LiteralInterpretationMut,
6		ReverseBlankIdInterpretation, ReverseIriInterpretation, ReverseTermInterpretation,
7		TermInterpretationMut,
8	},
9	vocabulary::{
10		EmbedIntoVocabulary, ExtractedFromVocabulary, IriVocabularyMut, LiteralVocabularyMut,
11	},
12	Generator, Id, Interpretation, InterpretationMut, Quad, Term, Vocabulary,
13};
14
15use crate::{
16	CowRdfTerm, GraphVisitor, InterpretedQuad, LinkedData, LinkedDataGraph, LinkedDataResource,
17	LinkedDataSubject, PredicateObjectsVisitor, RdfId, RdfQuad, ResourceInterpretation,
18	SubjectVisitor, Visitor,
19};
20
21pub fn to_interpreted_quads<I, V>(
22	vocabulary: &mut V,
23	interpretation: &mut I,
24	value: &impl LinkedData<I, V>,
25) -> Result<Vec<InterpretedQuad<I>>, IntoQuadsError>
26where
27	I: Interpretation
28		+ InterpretationMut<V>
29		+ TermInterpretationMut<V::Iri, V::BlankId, V::Literal>,
30	I::Resource: Clone,
31	V: Vocabulary + IriVocabularyMut + LiteralVocabularyMut,
32	V::Iri: Clone,
33	V::BlankId: Clone,
34{
35	value.visit(QuadSerializer {
36		vocabulary,
37		interpretation,
38		domain: &mut InterpretationDomain,
39		result: Vec::new(),
40	})
41}
42
43pub fn to_interpreted_subject_quads<I, V>(
44	vocabulary: &mut V,
45	interpretation: &mut I,
46	graph: Option<&I::Resource>,
47	value: &(impl LinkedDataSubject<I, V> + LinkedDataResource<I, V>),
48) -> Result<(I::Resource, Vec<InterpretedQuad<I>>), IntoQuadsError>
49where
50	I: Interpretation
51		+ InterpretationMut<V>
52		+ IriInterpretationMut<V::Iri>
53		+ BlankIdInterpretationMut<V::BlankId>
54		+ LiteralInterpretationMut<V::Literal>,
55	I::Resource: Clone,
56	V: Vocabulary + IriVocabularyMut + LiteralVocabularyMut,
57	V::Iri: Clone,
58	V::BlankId: Clone,
59{
60	let mut result = Vec::new();
61
62	let subject = match value.interpretation(vocabulary, interpretation) {
63		ResourceInterpretation::Interpreted(r) => r.clone(),
64		ResourceInterpretation::Uninterpreted(_) => interpretation.new_resource(vocabulary),
65	};
66
67	value.visit_subject(QuadPropertiesSerializer {
68		vocabulary,
69		interpretation,
70		domain: &mut InterpretationDomain,
71		graph,
72		subject: SubjectOrObject::Subject(&subject),
73		result: &mut result,
74	})?;
75
76	Ok((subject, result))
77}
78
79pub fn to_interpreted_graph_quads<I, V>(
80	vocabulary: &mut V,
81	interpretation: &mut I,
82	value: &(impl LinkedDataGraph<I, V> + LinkedDataResource<I, V>),
83) -> Result<(I::Resource, Vec<InterpretedQuad<I>>), IntoQuadsError>
84where
85	I: Interpretation
86		+ InterpretationMut<V>
87		+ IriInterpretationMut<V::Iri>
88		+ BlankIdInterpretationMut<V::BlankId>
89		+ LiteralInterpretationMut<V::Literal>,
90	I::Resource: Clone,
91	V: Vocabulary + IriVocabularyMut + LiteralVocabularyMut,
92	V::Iri: Clone,
93	V::BlankId: Clone,
94{
95	let mut result = Vec::new();
96
97	let graph = match value.interpretation(vocabulary, interpretation) {
98		ResourceInterpretation::Interpreted(r) => r.clone(),
99		ResourceInterpretation::Uninterpreted(_) => interpretation.new_resource(vocabulary),
100	};
101
102	value.visit_graph(QuadGraphSerializer {
103		vocabulary,
104		interpretation,
105		domain: &mut InterpretationDomain,
106		graph: Some(&graph),
107		result: &mut result,
108	})?;
109
110	Ok((graph, result))
111}
112
113pub fn to_lexical_quads_with<I, V: Vocabulary>(
114	vocabulary: &mut V,
115	interpretation: &mut I,
116	value: &impl LinkedData<I, V>,
117) -> Result<Vec<RdfQuad>, IntoQuadsError>
118where
119	I: Interpretation
120		+ InterpretationMut<V>
121		+ ReverseTermInterpretation<Iri = V::Iri, BlankId = V::BlankId, Literal = V::Literal>,
122{
123	let mut domain = LexicalDomain;
124
125	value.visit(QuadSerializer {
126		vocabulary,
127		interpretation,
128		domain: &mut domain,
129		result: Vec::new(),
130	})
131}
132
133pub fn to_lexical_subject_quads_with<I, V: Vocabulary>(
134	vocabulary: &mut V,
135	interpretation: &mut I,
136	graph: Option<&Id>,
137	value: &(impl LinkedDataSubject<I, V> + LinkedDataResource<I, V>),
138) -> Result<(Id, Vec<RdfQuad>), IntoQuadsError>
139where
140	I: Interpretation
141		+ InterpretationMut<V>
142		+ ReverseTermInterpretation<Iri = V::Iri, BlankId = V::BlankId, Literal = V::Literal>,
143	I::Resource: Clone,
144{
145	let mut result = Vec::new();
146
147	let i = value.interpretation(vocabulary, interpretation);
148	let subject = LexicalDomain.subject(vocabulary, interpretation, i)?;
149
150	value.visit_subject(QuadPropertiesSerializer {
151		vocabulary,
152		interpretation,
153		domain: &mut LexicalDomain,
154		graph,
155		subject: SubjectOrObject::Subject(&subject),
156		result: &mut result,
157	})?;
158
159	Ok((subject, result))
160}
161
162pub fn to_lexical_quads<G: Generator>(
163	generator: G,
164	value: &impl LinkedData<interpretation::WithGenerator<G>>,
165) -> Result<Vec<RdfQuad>, IntoQuadsError> {
166	let mut interpretation = rdf_types::interpretation::WithGenerator::new((), generator);
167	to_lexical_quads_with(&mut (), &mut interpretation, value)
168}
169
170pub fn to_lexical_subject_quads<G: Generator>(
171	generator: G,
172	graph: Option<&Id>,
173	value: &(impl LinkedDataSubject<interpretation::WithGenerator<G>>
174	      + LinkedDataResource<interpretation::WithGenerator<G>>),
175) -> Result<(Id, Vec<RdfQuad>), IntoQuadsError> {
176	let mut interpretation = rdf_types::interpretation::WithGenerator::new((), generator);
177	to_lexical_subject_quads_with(&mut (), &mut interpretation, graph, value)
178}
179
180pub fn to_quads_with<I, V>(
181	vocabulary: &mut V,
182	interpretation: &mut I,
183	value: &impl LinkedData<I, V>,
184) -> Result<Vec<RdfQuad<V>>, IntoQuadsError>
185where
186	V: Vocabulary + IriVocabularyMut + LiteralVocabularyMut,
187	V::BlankId: Clone,
188	V::Iri: Clone,
189	V::Literal: Clone,
190	I: InterpretationMut<V>
191		+ ReverseTermInterpretation<Iri = V::Iri, BlankId = V::BlankId, Literal = V::Literal>,
192{
193	let mut domain = VocabularyDomain;
194
195	value.visit(QuadSerializer {
196		vocabulary,
197		interpretation,
198		domain: &mut domain,
199		result: Vec::new(),
200	})
201}
202
203pub fn to_quads<G: Generator>(
204	generator: G,
205	value: &impl LinkedData<interpretation::WithGenerator<G>>,
206) -> Result<Vec<RdfQuad>, IntoQuadsError> {
207	let mut interpretation = interpretation::WithGenerator::new((), generator);
208	to_quads_with(&mut (), &mut interpretation, value)
209}
210
211#[derive(Debug, thiserror::Error)]
212pub enum IntoQuadsError {
213	#[error("invalid graph label")]
214	Graph,
215
216	#[error("invalid subject")]
217	Subject,
218
219	#[error("invalid predicate")]
220	Predicate,
221
222	#[error("missing lexical representation")]
223	MissingLexicalRepresentation,
224}
225
226trait Domain<I: Interpretation, V: Vocabulary> {
227	type Subject: Clone;
228	type Predicate: Clone;
229	type Object;
230	type ObjectRef<'a>: Copy
231	where
232		V::Iri: 'a,
233		V::BlankId: 'a,
234		V::Literal: 'a,
235		I::Resource: 'a;
236
237	fn subject(
238		&mut self,
239		vocabulary: &mut V,
240		interpretation: &mut I,
241		value: ResourceInterpretation<I, V>,
242	) -> Result<Self::Subject, IntoQuadsError>;
243
244	fn predicate(
245		&mut self,
246		vocabulary: &mut V,
247		interpretation: &mut I,
248		value: ResourceInterpretation<I, V>,
249	) -> Result<Self::Predicate, IntoQuadsError>;
250
251	fn object(
252		&mut self,
253		vocabulary: &mut V,
254		interpretation: &mut I,
255		value: ResourceInterpretation<I, V>,
256	) -> Result<Self::Object, IntoQuadsError>;
257
258	fn graph(
259		&mut self,
260		vocabulary: &mut V,
261		interpretation: &mut I,
262		value: ResourceInterpretation<I, V>,
263	) -> Result<Self::Subject, IntoQuadsError>;
264
265	fn object_as_subject<'a>(
266		&self,
267		object: &'a Self::Object,
268	) -> Result<&'a Self::Subject, IntoQuadsError>;
269
270	fn subject_as_object<'a>(
271		&self,
272		subject: &'a Self::Subject,
273	) -> Result<Self::ObjectRef<'a>, IntoQuadsError>
274	where
275		V::Iri: 'a,
276		V::BlankId: 'a,
277		V::Literal: 'a,
278		I::Resource: 'a;
279
280	fn object_as_ref<'a>(object: &'a Self::Object) -> Self::ObjectRef<'a>
281	where
282		V::Iri: 'a,
283		V::BlankId: 'a,
284		V::Literal: 'a,
285		I::Resource: 'a;
286
287	fn cloned_object_ref<'a>(object_ref: Self::ObjectRef<'a>) -> Self::Object
288	where
289		V::Iri: 'a,
290		V::BlankId: 'a,
291		V::Literal: 'a,
292		I::Resource: 'a;
293}
294
295type DomainQuad<I, V, D> = Quad<
296	<D as Domain<I, V>>::Subject,
297	<D as Domain<I, V>>::Predicate,
298	<D as Domain<I, V>>::Object,
299	<D as Domain<I, V>>::Subject,
300>;
301
302struct VocabularyDomain;
303
304#[allow(clippy::type_complexity)]
305fn resource_term<I>(
306	interpretation: &I,
307	r: &I::Resource,
308) -> Result<Term<Id<I::Iri, I::BlankId>, I::Literal>, IntoQuadsError>
309where
310	I: ReverseTermInterpretation,
311	I::Iri: Clone,
312	I::BlankId: Clone,
313	I::Literal: Clone,
314{
315	if let Some(iri) = interpretation.iris_of(r).next() {
316		return Ok(Term::Id(Id::Iri(iri.clone())));
317	}
318
319	if let Some(lit) = interpretation.literals_of(r).next() {
320		return Ok(Term::Literal(lit.clone()));
321	}
322
323	if let Some(blank_id) = interpretation.blank_ids_of(r).next() {
324		return Ok(Term::Id(Id::Blank(blank_id.clone())));
325	}
326
327	Err(IntoQuadsError::MissingLexicalRepresentation)
328}
329
330impl<I: InterpretationMut<V>, V: Vocabulary> Domain<I, V> for VocabularyDomain
331where
332	V: IriVocabularyMut + LiteralVocabularyMut,
333	V::Iri: Clone,
334	V::BlankId: Clone,
335	V::Literal: Clone,
336	I: ReverseTermInterpretation<Iri = V::Iri, BlankId = V::BlankId, Literal = V::Literal>,
337{
338	type Subject = RdfId<V>;
339	type Predicate = V::Iri;
340	type Object = Term<RdfId<V>, V::Literal>;
341	type ObjectRef<'a>
342		= Term<&'a RdfId<V>, &'a V::Literal>
343	where
344		V::Iri: 'a,
345		V::BlankId: 'a,
346		V::Literal: 'a,
347		I::Resource: 'a;
348
349	fn subject(
350		&mut self,
351		vocabulary: &mut V,
352		interpretation: &mut I,
353		value: ResourceInterpretation<I, V>,
354	) -> Result<Self::Subject, IntoQuadsError> {
355		match value {
356			ResourceInterpretation::Interpreted(r) => {
357				if let Some(iri) = interpretation.iris_of(r).next() {
358					return Ok(Id::Iri(iri.clone()));
359				}
360
361				if let Some(blank_id) = interpretation.blank_ids_of(r).next() {
362					return Ok(Id::Blank(blank_id.clone()));
363				}
364
365				Err(IntoQuadsError::MissingLexicalRepresentation)
366			}
367			ResourceInterpretation::Uninterpreted(u) => match u {
368				Some(u) => u.into_owned().into_id(),
369				None => {
370					let r = interpretation.new_resource(vocabulary);
371					resource_term(interpretation, &r)?.into_id()
372				}
373			}
374			.ok_or(IntoQuadsError::Subject),
375		}
376	}
377
378	fn predicate(
379		&mut self,
380		_vocabulary: &mut V,
381		interpretation: &mut I,
382		value: ResourceInterpretation<I, V>,
383	) -> Result<Self::Predicate, IntoQuadsError> {
384		match value {
385			ResourceInterpretation::Interpreted(r) => {
386				if let Some(iri) = interpretation.iris_of(r).next() {
387					return Ok(iri.clone());
388				}
389
390				Err(IntoQuadsError::Predicate)
391			}
392			ResourceInterpretation::Uninterpreted(u) => match u {
393				Some(CowRdfTerm::Owned(Term::Id(Id::Iri(iri)))) => Ok(iri),
394				Some(CowRdfTerm::Borrowed(Term::Id(Id::Iri(iri)))) => Ok(iri.clone()),
395				_ => Err(IntoQuadsError::Predicate),
396			},
397		}
398	}
399
400	fn object(
401		&mut self,
402		vocabulary: &mut V,
403		interpretation: &mut I,
404		value: ResourceInterpretation<I, V>,
405	) -> Result<Self::Object, IntoQuadsError> {
406		match value {
407			ResourceInterpretation::Interpreted(r) => resource_term(interpretation, r),
408			ResourceInterpretation::Uninterpreted(u) => {
409				let term = match u {
410					Some(CowRdfTerm::Owned(Term::Id(id))) => Term::Id(id),
411					Some(CowRdfTerm::Owned(Term::Literal(l))) => {
412						Term::Literal(l.embed_into_vocabulary(vocabulary))
413					}
414					Some(CowRdfTerm::Borrowed(Term::Id(id))) => Term::Id(id.cloned()),
415					Some(CowRdfTerm::Borrowed(Term::Literal(l))) => {
416						Term::Literal(l.into_owned().embed_into_vocabulary(vocabulary))
417					}
418					None => {
419						let r = interpretation.new_resource(vocabulary);
420						resource_term(interpretation, &r)?
421					}
422				};
423
424				Ok(term)
425			}
426		}
427	}
428
429	fn graph(
430		&mut self,
431		vocabulary: &mut V,
432		interpretation: &mut I,
433		value: ResourceInterpretation<I, V>,
434	) -> Result<Self::Subject, IntoQuadsError> {
435		match value {
436			ResourceInterpretation::Interpreted(r) => {
437				if let Some(iri) = interpretation.iris_of(r).next() {
438					return Ok(Id::Iri(iri.clone()));
439				}
440
441				if let Some(blank_id) = interpretation.blank_ids_of(r).next() {
442					return Ok(Id::Blank(blank_id.clone()));
443				}
444
445				Err(IntoQuadsError::MissingLexicalRepresentation)
446			}
447			ResourceInterpretation::Uninterpreted(u) => match u {
448				Some(u) => u.into_owned().into_id(),
449				None => {
450					let r = interpretation.new_resource(vocabulary);
451					resource_term(interpretation, &r)?.into_id()
452				}
453			}
454			.ok_or(IntoQuadsError::Subject),
455		}
456	}
457
458	fn object_as_subject<'a>(
459		&self,
460		object: &'a Self::Object,
461	) -> Result<&'a Self::Subject, IntoQuadsError> {
462		match object {
463			Term::Id(id) => Ok(id),
464			Term::Literal(_) => Err(IntoQuadsError::Subject),
465		}
466	}
467
468	fn subject_as_object<'a>(
469		&self,
470		subject: &'a Self::Subject,
471	) -> Result<Self::ObjectRef<'a>, IntoQuadsError>
472	where
473		V::Iri: 'a,
474		V::BlankId: 'a,
475		V::Literal: 'a,
476		I::Resource: 'a,
477	{
478		Ok(Term::Id(subject))
479	}
480
481	fn object_as_ref<'a>(object: &'a Self::Object) -> Self::ObjectRef<'a>
482	where
483		V::Iri: 'a,
484		V::BlankId: 'a,
485		V::Literal: 'a,
486		I::Resource: 'a,
487	{
488		object.as_ref()
489	}
490
491	fn cloned_object_ref<'a>(object_ref: Self::ObjectRef<'a>) -> Self::Object
492	where
493		V::Iri: 'a,
494		V::BlankId: 'a,
495		V::Literal: 'a,
496		I::Resource: 'a,
497	{
498		object_ref.cloned()
499	}
500}
501
502struct InterpretationDomain;
503
504impl<I: Interpretation, V: Vocabulary> Domain<I, V> for InterpretationDomain
505where
506	I: InterpretationMut<V>
507		+ IriInterpretationMut<V::Iri>
508		+ BlankIdInterpretationMut<V::BlankId>
509		+ LiteralInterpretationMut<V::Literal>,
510	I::Resource: Clone,
511	V: IriVocabularyMut + LiteralVocabularyMut,
512	V::Iri: Clone,
513	V::BlankId: Clone,
514{
515	type Subject = I::Resource;
516	type Predicate = I::Resource;
517	type Object = I::Resource;
518	type ObjectRef<'a>
519		= &'a I::Resource
520	where
521		V::Iri: 'a,
522		V::BlankId: 'a,
523		V::Literal: 'a,
524		I::Resource: 'a;
525
526	fn subject(
527		&mut self,
528		vocabulary: &mut V,
529		interpretation: &mut I,
530		value: ResourceInterpretation<I, V>,
531	) -> Result<Self::Subject, IntoQuadsError> {
532		match value {
533			ResourceInterpretation::Interpreted(r) => Ok(r.clone()),
534			ResourceInterpretation::Uninterpreted(u) => match u {
535				Some(CowRdfTerm::Owned(Term::Id(Id::Iri(iri)))) => {
536					Ok(interpretation.interpret_iri(iri))
537				}
538				Some(CowRdfTerm::Borrowed(Term::Id(Id::Iri(iri)))) => {
539					Ok(interpretation.interpret_iri(iri.clone()))
540				}
541				Some(CowRdfTerm::Owned(Term::Id(Id::Blank(b)))) => {
542					Ok(interpretation.interpret_blank_id(b))
543				}
544				Some(CowRdfTerm::Borrowed(Term::Id(Id::Blank(b)))) => {
545					Ok(interpretation.interpret_blank_id(b.clone()))
546				}
547				Some(CowRdfTerm::Owned(Term::Literal(_))) => Err(IntoQuadsError::Subject),
548				Some(CowRdfTerm::Borrowed(Term::Literal(_))) => Err(IntoQuadsError::Subject),
549				None => Ok(interpretation.new_resource(vocabulary)),
550			},
551		}
552	}
553
554	fn predicate(
555		&mut self,
556		_vocabulary: &mut V,
557		interpretation: &mut I,
558		value: ResourceInterpretation<I, V>,
559	) -> Result<Self::Predicate, IntoQuadsError> {
560		match value {
561			ResourceInterpretation::Interpreted(r) => Ok(r.clone()),
562			ResourceInterpretation::Uninterpreted(u) => match u {
563				Some(CowRdfTerm::Owned(Term::Id(Id::Iri(iri)))) => {
564					Ok(interpretation.interpret_iri(iri))
565				}
566				Some(CowRdfTerm::Borrowed(Term::Id(Id::Iri(iri)))) => {
567					Ok(interpretation.interpret_iri(iri.clone()))
568				}
569				_ => Err(IntoQuadsError::Predicate),
570			},
571		}
572	}
573
574	fn object(
575		&mut self,
576		vocabulary: &mut V,
577		interpretation: &mut I,
578		value: ResourceInterpretation<I, V>,
579	) -> Result<Self::Object, IntoQuadsError> {
580		match value {
581			ResourceInterpretation::Interpreted(r) => Ok(r.clone()),
582			ResourceInterpretation::Uninterpreted(u) => match u {
583				Some(CowRdfTerm::Owned(Term::Id(Id::Iri(iri)))) => {
584					Ok(interpretation.interpret_iri(iri))
585				}
586				Some(CowRdfTerm::Borrowed(Term::Id(Id::Iri(iri)))) => {
587					Ok(interpretation.interpret_iri(iri.clone()))
588				}
589				Some(CowRdfTerm::Owned(Term::Id(Id::Blank(b)))) => {
590					Ok(interpretation.interpret_blank_id(b))
591				}
592				Some(CowRdfTerm::Borrowed(Term::Id(Id::Blank(b)))) => {
593					Ok(interpretation.interpret_blank_id(b.clone()))
594				}
595				Some(CowRdfTerm::Owned(Term::Literal(l))) => {
596					let l = l.embed_into_vocabulary(vocabulary);
597					let l = interpretation.interpret_literal(l);
598					Ok(l)
599				}
600				Some(CowRdfTerm::Borrowed(Term::Literal(l))) => {
601					let l = l.into_owned().embed_into_vocabulary(vocabulary);
602					let l = interpretation.interpret_literal(l);
603					Ok(l)
604				}
605				None => Ok(interpretation.new_resource(vocabulary)),
606			},
607		}
608	}
609
610	fn graph(
611		&mut self,
612		vocabulary: &mut V,
613		interpretation: &mut I,
614		value: ResourceInterpretation<I, V>,
615	) -> Result<Self::Subject, IntoQuadsError> {
616		match value {
617			ResourceInterpretation::Interpreted(r) => Ok(r.clone()),
618			ResourceInterpretation::Uninterpreted(u) => match u {
619				Some(CowRdfTerm::Owned(Term::Id(Id::Iri(iri)))) => {
620					Ok(interpretation.interpret_iri(iri))
621				}
622				Some(CowRdfTerm::Borrowed(Term::Id(Id::Iri(iri)))) => {
623					Ok(interpretation.interpret_iri(iri.clone()))
624				}
625				Some(CowRdfTerm::Owned(Term::Id(Id::Blank(b)))) => {
626					Ok(interpretation.interpret_blank_id(b))
627				}
628				Some(CowRdfTerm::Borrowed(Term::Id(Id::Blank(b)))) => {
629					Ok(interpretation.interpret_blank_id(b.clone()))
630				}
631				Some(CowRdfTerm::Owned(Term::Literal(_))) => Err(IntoQuadsError::Graph),
632				Some(CowRdfTerm::Borrowed(Term::Literal(_))) => Err(IntoQuadsError::Graph),
633				None => Ok(interpretation.new_resource(vocabulary)),
634			},
635		}
636	}
637
638	fn object_as_subject<'a>(
639		&self,
640		object: &'a Self::Object,
641	) -> Result<&'a Self::Subject, IntoQuadsError> {
642		Ok(object)
643	}
644
645	fn subject_as_object<'a>(
646		&self,
647		subject: &'a Self::Subject,
648	) -> Result<Self::ObjectRef<'a>, IntoQuadsError>
649	where
650		V::Iri: 'a,
651		V::BlankId: 'a,
652		V::Literal: 'a,
653		I::Resource: 'a,
654	{
655		Ok(subject)
656	}
657
658	fn object_as_ref<'a>(object: &'a Self::Object) -> Self::ObjectRef<'a>
659	where
660		V::Iri: 'a,
661		V::BlankId: 'a,
662		V::Literal: 'a,
663		I::Resource: 'a,
664	{
665		object
666	}
667
668	fn cloned_object_ref<'a>(object_ref: Self::ObjectRef<'a>) -> Self::Object
669	where
670		V::Iri: 'a,
671		V::BlankId: 'a,
672		V::Literal: 'a,
673		I::Resource: 'a,
674	{
675		object_ref.clone()
676	}
677}
678
679struct LexicalDomain;
680
681fn lexical_term<V: Vocabulary>(vocabulary: &V, term: CowRdfTerm<V>) -> Term {
682	match term {
683		CowRdfTerm::Borrowed(Term::Id(Id::Iri(iri))) => {
684			Term::Id(Id::Iri(vocabulary.iri(iri).unwrap().to_owned()))
685		}
686		CowRdfTerm::Owned(Term::Id(Id::Iri(iri))) => {
687			Term::Id(Id::Iri(vocabulary.owned_iri(iri).ok().unwrap()))
688		}
689		CowRdfTerm::Borrowed(Term::Id(Id::Blank(blank_id))) => {
690			Term::Id(Id::Blank(vocabulary.blank_id(blank_id).unwrap().to_owned()))
691		}
692		CowRdfTerm::Owned(Term::Id(Id::Blank(blank_id))) => {
693			Term::Id(Id::Blank(vocabulary.owned_blank_id(blank_id).ok().unwrap()))
694		}
695		CowRdfTerm::Borrowed(Term::Literal(lit)) => Term::Literal(lit.into_lexical(vocabulary)),
696		CowRdfTerm::Owned(Term::Literal(lit)) => Term::Literal(lit.into_lexical(vocabulary)),
697	}
698}
699
700fn resource_lexical_term<V: Vocabulary, I>(
701	vocabulary: &V,
702	interpretation: &I,
703	r: &I::Resource,
704) -> Result<Term<Id, rdf_types::Literal>, IntoQuadsError>
705where
706	I: ReverseTermInterpretation<Iri = V::Iri, BlankId = V::BlankId, Literal = V::Literal>,
707{
708	if let Some(iri) = interpretation.iris_of(r).next() {
709		let iri = vocabulary.iri(iri).unwrap();
710		return Ok(Term::Id(Id::Iri(iri.to_owned())));
711	}
712
713	if let Some(lit) = interpretation.literals_of(r).next() {
714		return Ok(Term::Literal(
715			vocabulary
716				.literal(lit)
717				.unwrap()
718				.extracted_from_vocabulary(vocabulary),
719		));
720	}
721
722	if let Some(blank_id) = interpretation.blank_ids_of(r).next() {
723		let blank_id = vocabulary.blank_id(blank_id).unwrap();
724		return Ok(Term::Id(Id::Blank(blank_id.to_owned())));
725	}
726
727	Err(IntoQuadsError::MissingLexicalRepresentation)
728}
729
730impl<I: InterpretationMut<V>, V: Vocabulary> Domain<I, V> for LexicalDomain
731where
732	I: ReverseTermInterpretation<Iri = V::Iri, BlankId = V::BlankId, Literal = V::Literal>,
733{
734	type Subject = Id;
735	type Predicate = IriBuf;
736	type Object = Term;
737	type ObjectRef<'a>
738		= Term<&'a Id, &'a rdf_types::Literal>
739	where
740		V::Iri: 'a,
741		V::BlankId: 'a,
742		V::Literal: 'a,
743		I::Resource: 'a;
744
745	fn subject(
746		&mut self,
747		vocabulary: &mut V,
748		interpretation: &mut I,
749		value: ResourceInterpretation<I, V>,
750	) -> Result<Self::Subject, IntoQuadsError> {
751		match value {
752			ResourceInterpretation::Interpreted(r) => {
753				if let Some(iri) = interpretation.iris_of(r).next() {
754					let iri = vocabulary.iri(iri).unwrap();
755					return Ok(Id::Iri(iri.to_owned()));
756				}
757
758				if let Some(blank_id) = interpretation.blank_ids_of(r).next() {
759					let blank_id = vocabulary.blank_id(blank_id).unwrap();
760					return Ok(Id::Blank(blank_id.to_owned()));
761				}
762
763				Err(IntoQuadsError::MissingLexicalRepresentation)
764			}
765			ResourceInterpretation::Uninterpreted(u) => u
766				.map(|t| Ok(lexical_term(vocabulary, t)))
767				.unwrap_or_else(|| {
768					let r = interpretation.new_resource(vocabulary);
769					resource_lexical_term(vocabulary, interpretation, &r)
770				})?
771				.into_id()
772				.ok_or(IntoQuadsError::Subject),
773		}
774	}
775
776	fn predicate(
777		&mut self,
778		vocabulary: &mut V,
779		interpretation: &mut I,
780		value: ResourceInterpretation<I, V>,
781	) -> Result<Self::Predicate, IntoQuadsError> {
782		match value {
783			ResourceInterpretation::Interpreted(r) => {
784				if let Some(iri) = interpretation.iris_of(r).next() {
785					let iri = vocabulary.iri(iri).unwrap();
786					return Ok(iri.to_owned());
787				}
788
789				Err(IntoQuadsError::Predicate)
790			}
791			ResourceInterpretation::Uninterpreted(u) => match u {
792				Some(CowRdfTerm::Owned(Term::Id(Id::Iri(iri)))) => {
793					Ok(vocabulary.owned_iri(iri).ok().unwrap())
794				}
795				Some(CowRdfTerm::Borrowed(Term::Id(Id::Iri(iri)))) => {
796					Ok(vocabulary.iri(iri).unwrap().to_owned())
797				}
798				_ => Err(IntoQuadsError::Predicate),
799			},
800		}
801	}
802
803	fn object(
804		&mut self,
805		vocabulary: &mut V,
806		interpretation: &mut I,
807		value: ResourceInterpretation<I, V>,
808	) -> Result<Self::Object, IntoQuadsError> {
809		match value {
810			ResourceInterpretation::Interpreted(r) => {
811				resource_lexical_term(vocabulary, interpretation, r)
812			}
813			ResourceInterpretation::Uninterpreted(u) => {
814				let term = match u {
815					Some(CowRdfTerm::Owned(Term::Id(Id::Iri(iri)))) => {
816						Term::Id(Id::Iri(vocabulary.owned_iri(iri).ok().unwrap()))
817					}
818					Some(CowRdfTerm::Borrowed(Term::Id(Id::Iri(iri)))) => {
819						Term::Id(Id::Iri(vocabulary.iri(iri).unwrap().to_owned()))
820					}
821					Some(CowRdfTerm::Owned(Term::Id(Id::Blank(blank_id)))) => {
822						Term::Id(Id::Blank(vocabulary.owned_blank_id(blank_id).ok().unwrap()))
823					}
824					Some(CowRdfTerm::Borrowed(Term::Id(Id::Blank(blank_id)))) => {
825						Term::Id(Id::Blank(vocabulary.blank_id(blank_id).unwrap().to_owned()))
826					}
827					Some(CowRdfTerm::Owned(Term::Literal(lit))) => {
828						Term::Literal(lit.into_lexical(vocabulary))
829					}
830					Some(CowRdfTerm::Borrowed(Term::Literal(lit))) => {
831						Term::Literal(lit.into_lexical(vocabulary))
832					}
833					None => {
834						let r = interpretation.new_resource(vocabulary);
835						resource_lexical_term(vocabulary, interpretation, &r)?
836					}
837				};
838
839				Ok(term)
840			}
841		}
842	}
843
844	fn graph(
845		&mut self,
846		vocabulary: &mut V,
847		interpretation: &mut I,
848		value: ResourceInterpretation<I, V>,
849	) -> Result<Self::Subject, IntoQuadsError> {
850		match value {
851			ResourceInterpretation::Interpreted(r) => {
852				if let Some(iri) = interpretation.iris_of(r).next() {
853					let iri = vocabulary.iri(iri).unwrap();
854					return Ok(Id::Iri(iri.to_owned()));
855				}
856
857				if let Some(blank_id) = interpretation.blank_ids_of(r).next() {
858					let blank_id = vocabulary.blank_id(blank_id).unwrap();
859					return Ok(Id::Blank(blank_id.to_owned()));
860				}
861
862				Err(IntoQuadsError::MissingLexicalRepresentation)
863			}
864			ResourceInterpretation::Uninterpreted(u) => u
865				.map(|t| Ok(lexical_term(vocabulary, t)))
866				.unwrap_or_else(|| {
867					let r = interpretation.new_resource(vocabulary);
868					resource_lexical_term(vocabulary, interpretation, &r)
869				})?
870				.into_id()
871				.ok_or(IntoQuadsError::Graph),
872		}
873	}
874
875	fn object_as_subject<'a>(
876		&self,
877		object: &'a Self::Object,
878	) -> Result<&'a Self::Subject, IntoQuadsError> {
879		match object {
880			Term::Id(id) => Ok(id),
881			Term::Literal(_) => Err(IntoQuadsError::Subject),
882		}
883	}
884
885	fn subject_as_object<'a>(
886		&self,
887		subject: &'a Self::Subject,
888	) -> Result<Self::ObjectRef<'a>, IntoQuadsError>
889	where
890		V::Iri: 'a,
891		V::BlankId: 'a,
892		V::Literal: 'a,
893		I::Resource: 'a,
894	{
895		Ok(Term::Id(subject))
896	}
897
898	fn object_as_ref<'a>(object: &'a Self::Object) -> Self::ObjectRef<'a>
899	where
900		V::Iri: 'a,
901		V::BlankId: 'a,
902		V::Literal: 'a,
903		I::Resource: 'a,
904	{
905		object.as_ref()
906	}
907
908	fn cloned_object_ref<'a>(object_ref: Self::ObjectRef<'a>) -> Self::Object
909	where
910		V::Iri: 'a,
911		V::BlankId: 'a,
912		V::Literal: 'a,
913		I::Resource: 'a,
914	{
915		object_ref.cloned()
916	}
917}
918
919/// A simple serializer generating a list of `Quad`s.
920struct QuadSerializer<'a, I: Interpretation, V: Vocabulary, D: Domain<I, V>> {
921	vocabulary: &'a mut V,
922	interpretation: &'a mut I,
923	domain: &'a mut D,
924	result: Vec<DomainQuad<I, V, D>>,
925}
926
927impl<I: Interpretation, V: Vocabulary, D: Domain<I, V>> Visitor<I, V>
928	for QuadSerializer<'_, I, V, D>
929{
930	type Ok = Vec<DomainQuad<I, V, D>>;
931	type Error = IntoQuadsError;
932
933	fn default_graph<T>(&mut self, value: &T) -> Result<(), Self::Error>
934	where
935		T: ?Sized + crate::LinkedDataGraph<I, V>,
936	{
937		let graph_serializer = QuadGraphSerializer {
938			vocabulary: self.vocabulary,
939			interpretation: self.interpretation,
940			domain: self.domain,
941			result: &mut self.result,
942			graph: None,
943		};
944
945		value.visit_graph(graph_serializer)
946	}
947
948	fn named_graph<T>(&mut self, value: &T) -> Result<(), Self::Error>
949	where
950		T: ?Sized + LinkedDataResource<I, V> + crate::LinkedDataGraph<I, V>,
951	{
952		let i = value.interpretation(self.vocabulary, self.interpretation);
953		let graph = self.domain.graph(self.vocabulary, self.interpretation, i)?;
954
955		let graph_serializer = QuadGraphSerializer {
956			vocabulary: self.vocabulary,
957			interpretation: self.interpretation,
958			domain: self.domain,
959			result: &mut self.result,
960			graph: Some(&graph),
961		};
962
963		value.visit_graph(graph_serializer)
964	}
965
966	fn end(self) -> Result<Self::Ok, Self::Error> {
967		Ok(self.result)
968	}
969}
970
971struct QuadGraphSerializer<'a, I: Interpretation, V: Vocabulary, D: Domain<I, V>> {
972	vocabulary: &'a mut V,
973	interpretation: &'a mut I,
974	domain: &'a mut D,
975	result: &'a mut Vec<DomainQuad<I, V, D>>,
976	graph: Option<&'a D::Subject>,
977}
978
979impl<I: Interpretation, V: Vocabulary, D: Domain<I, V>> GraphVisitor<I, V>
980	for QuadGraphSerializer<'_, I, V, D>
981{
982	type Ok = ();
983	type Error = IntoQuadsError;
984
985	fn subject<T>(&mut self, value: &T) -> Result<(), Self::Error>
986	where
987		T: ?Sized + LinkedDataResource<I, V> + crate::LinkedDataSubject<I, V>,
988	{
989		let i = value.interpretation(self.vocabulary, self.interpretation);
990		let term = self
991			.domain
992			.subject(self.vocabulary, self.interpretation, i)?;
993
994		let properties_serializer = QuadPropertiesSerializer {
995			vocabulary: self.vocabulary,
996			interpretation: self.interpretation,
997			domain: self.domain,
998			result: self.result,
999			graph: self.graph,
1000			subject: SubjectOrObject::Subject(&term),
1001		};
1002
1003		value.visit_subject(properties_serializer)
1004	}
1005
1006	fn end(self) -> Result<Self::Ok, Self::Error> {
1007		Ok(())
1008	}
1009}
1010
1011struct QuadPropertiesSerializer<'a, I: Interpretation, V: Vocabulary, D: Domain<I, V>> {
1012	vocabulary: &'a mut V,
1013	interpretation: &'a mut I,
1014	domain: &'a mut D,
1015	result: &'a mut Vec<DomainQuad<I, V, D>>,
1016	graph: Option<&'a D::Subject>,
1017	subject: SubjectOrObject<'a, I, V, D>,
1018}
1019
1020#[derive(Educe)]
1021#[educe(Clone, Copy)]
1022enum SubjectOrObject<'a, I: Interpretation, V: Vocabulary, D: Domain<I, V>> {
1023	Subject(&'a D::Subject),
1024	Object(&'a D::Object),
1025}
1026
1027impl<'a, I: Interpretation, V: Vocabulary, D: Domain<I, V>> SubjectOrObject<'a, I, V, D> {
1028	fn into_subject(self, domain: &D) -> Result<&'a D::Subject, IntoQuadsError> {
1029		match self {
1030			Self::Subject(s) => Ok(s),
1031			Self::Object(o) => domain.object_as_subject(o),
1032		}
1033	}
1034
1035	fn into_object(self, domain: &D) -> Result<D::ObjectRef<'a>, IntoQuadsError> {
1036		match self {
1037			Self::Subject(s) => domain.subject_as_object(s),
1038			Self::Object(o) => Ok(D::object_as_ref(o)),
1039		}
1040	}
1041}
1042
1043impl<I: Interpretation, V: Vocabulary, D: Domain<I, V>> SubjectVisitor<I, V>
1044	for QuadPropertiesSerializer<'_, I, V, D>
1045{
1046	type Ok = ();
1047	type Error = IntoQuadsError;
1048
1049	fn predicate<L, T>(&mut self, predicate: &L, value: &T) -> Result<(), Self::Error>
1050	where
1051		L: ?Sized + LinkedDataResource<I, V>,
1052		T: ?Sized + crate::LinkedDataPredicateObjects<I, V>,
1053	{
1054		let subject = self.subject.into_subject(self.domain)?;
1055
1056		let i = predicate.interpretation(self.vocabulary, self.interpretation);
1057		let term = self
1058			.domain
1059			.predicate(self.vocabulary, self.interpretation, i)?;
1060
1061		let objects_serializer = ObjectsSerializer {
1062			vocabulary: self.vocabulary,
1063			interpretation: self.interpretation,
1064			domain: self.domain,
1065			result: self.result,
1066			graph: self.graph,
1067			subject,
1068			predicate: term,
1069		};
1070
1071		value.visit_objects(objects_serializer)
1072	}
1073
1074	fn reverse_predicate<L, T>(&mut self, predicate: &L, subjects: &T) -> Result<(), Self::Error>
1075	where
1076		L: ?Sized + LinkedDataResource<I, V>,
1077		T: ?Sized + crate::LinkedDataPredicateObjects<I, V>,
1078	{
1079		let object = self.subject.into_object(self.domain)?;
1080
1081		let i = predicate.interpretation(self.vocabulary, self.interpretation);
1082		let term = self
1083			.domain
1084			.predicate(self.vocabulary, self.interpretation, i)?;
1085
1086		let subjects_serializer = ReversePredicateSerializer {
1087			vocabulary: self.vocabulary,
1088			interpretation: self.interpretation,
1089			domain: self.domain,
1090			result: self.result,
1091			graph: self.graph,
1092			object,
1093			predicate: term,
1094		};
1095
1096		subjects.visit_objects(subjects_serializer)
1097	}
1098
1099	fn graph<T>(&mut self, value: &T) -> Result<(), Self::Error>
1100	where
1101		T: ?Sized + LinkedDataGraph<I, V>,
1102	{
1103		let graph = self.subject.into_subject(self.domain)?;
1104
1105		let graph_serializer = QuadGraphSerializer {
1106			vocabulary: self.vocabulary,
1107			interpretation: self.interpretation,
1108			domain: self.domain,
1109			result: self.result,
1110			graph: Some(graph),
1111		};
1112
1113		value.visit_graph(graph_serializer)
1114	}
1115
1116	fn include<T>(&mut self, value: &T) -> Result<(), Self::Error>
1117	where
1118		T: ?Sized + LinkedDataResource<I, V> + LinkedDataSubject<I, V>,
1119	{
1120		let i = value.interpretation(self.vocabulary, self.interpretation);
1121		let subject = self
1122			.domain
1123			.subject(self.vocabulary, self.interpretation, i)?;
1124
1125		value.visit_subject(QuadPropertiesSerializer {
1126			vocabulary: self.vocabulary,
1127			interpretation: self.interpretation,
1128			domain: self.domain,
1129			graph: self.graph,
1130			subject: SubjectOrObject::Subject(&subject),
1131			result: self.result,
1132		})?;
1133
1134		Ok(())
1135	}
1136
1137	fn end(self) -> Result<Self::Ok, Self::Error> {
1138		Ok(())
1139	}
1140}
1141
1142struct ObjectsSerializer<'a, I: Interpretation, V: Vocabulary, D: Domain<I, V>> {
1143	vocabulary: &'a mut V,
1144	interpretation: &'a mut I,
1145	domain: &'a mut D,
1146	result: &'a mut Vec<DomainQuad<I, V, D>>,
1147	graph: Option<&'a D::Subject>,
1148	subject: &'a D::Subject,
1149	predicate: D::Predicate,
1150}
1151
1152impl<I: Interpretation, V: Vocabulary, D: Domain<I, V>> PredicateObjectsVisitor<I, V>
1153	for ObjectsSerializer<'_, I, V, D>
1154{
1155	type Ok = ();
1156	type Error = IntoQuadsError;
1157
1158	fn object<T>(&mut self, value: &T) -> Result<(), Self::Error>
1159	where
1160		T: ?Sized + LinkedDataResource<I, V> + crate::LinkedDataSubject<I, V>,
1161	{
1162		let i = value.interpretation(self.vocabulary, self.interpretation);
1163		let term = self
1164			.domain
1165			.object(self.vocabulary, self.interpretation, i)?;
1166		let subject_serializer = QuadPropertiesSerializer {
1167			vocabulary: self.vocabulary,
1168			interpretation: self.interpretation,
1169			domain: self.domain,
1170			result: self.result,
1171			graph: self.graph,
1172			subject: SubjectOrObject::Object(&term),
1173		};
1174
1175		value.visit_subject(subject_serializer)?;
1176		self.result.push(Quad(
1177			self.subject.clone(),
1178			self.predicate.clone(),
1179			term,
1180			self.graph.cloned(),
1181		));
1182		Ok(())
1183	}
1184
1185	fn end(self) -> Result<Self::Ok, Self::Error> {
1186		Ok(())
1187	}
1188}
1189
1190struct ReversePredicateSerializer<'a, I: Interpretation, V: Vocabulary, D: Domain<I, V>> {
1191	vocabulary: &'a mut V,
1192	interpretation: &'a mut I,
1193	domain: &'a mut D,
1194	result: &'a mut Vec<DomainQuad<I, V, D>>,
1195	graph: Option<&'a D::Subject>,
1196	object: D::ObjectRef<'a>,
1197	predicate: D::Predicate,
1198}
1199
1200impl<I: Interpretation, V: Vocabulary, D: Domain<I, V>> PredicateObjectsVisitor<I, V>
1201	for ReversePredicateSerializer<'_, I, V, D>
1202{
1203	type Ok = ();
1204	type Error = IntoQuadsError;
1205
1206	fn object<T>(&mut self, value: &T) -> Result<(), Self::Error>
1207	where
1208		T: ?Sized + LinkedDataResource<I, V> + crate::LinkedDataSubject<I, V>,
1209	{
1210		let i = value.interpretation(self.vocabulary, self.interpretation);
1211		let subject = self
1212			.domain
1213			.subject(self.vocabulary, self.interpretation, i)?;
1214
1215		let subject_serializer = QuadPropertiesSerializer {
1216			vocabulary: self.vocabulary,
1217			interpretation: self.interpretation,
1218			domain: self.domain,
1219			result: self.result,
1220			graph: self.graph,
1221			subject: SubjectOrObject::Subject(&subject),
1222		};
1223
1224		value.visit_subject(subject_serializer)?;
1225		self.result.push(Quad(
1226			subject,
1227			self.predicate.clone(),
1228			D::cloned_object_ref(self.object),
1229			self.graph.cloned(),
1230		));
1231		Ok(())
1232	}
1233
1234	fn end(self) -> Result<Self::Ok, Self::Error> {
1235		Ok(())
1236	}
1237}