Skip to main content

linked_data_next/
quads.rs

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