1use educe::Educe;
2use iri_rs::IriBuf;
3use rdfx::generator::LocalGeneratorInterpretation;
4use rdfx::{
5 Id, Interpretation, InterpretationMut, IsGraph, IsObject, IsPredicate, IsSubject,
6 LocalGenerator, LocalTerm, Quad, Resource, Term,
7 interpretation::{
8 GenerativeInterpretation, LocalInterpretationMut, ReverseInterpretation,
9 ReverseLocalInterpretation,
10 },
11};
12
13use crate::{
14 CowRdfTerm, GraphVisitor, InterpretedQuad, LinkedData, LinkedDataGraph, LinkedDataResource,
15 LinkedDataSubject, OwnedRdfTerm, PredicateObjectsVisitor, RdfQuad, ResourceInterpretation,
16 SubjectVisitor, Visitor,
17};
18
19pub fn to_interpreted_quads<I>(
22 interpretation: &mut I,
23 value: &impl LinkedData<I>,
24) -> Result<Vec<InterpretedQuad<I>>, IntoQuadsError>
25where
26 I: Interpretation + InterpretationMut + LocalInterpretationMut + GenerativeInterpretation,
27 I::Resource: Clone + Resource,
28{
29 value.visit(QuadSerializer {
30 interpretation,
31 domain: &mut InterpretationDomain,
32 result: Vec::new(),
33 })
34}
35
36pub fn to_interpreted_subject_quads<I>(
39 interpretation: &mut I,
40 graph: Option<&I::Resource>,
41 value: &(impl LinkedDataSubject<I> + LinkedDataResource<I>),
42) -> Result<(I::Resource, Vec<InterpretedQuad<I>>), IntoQuadsError>
43where
44 I: Interpretation + InterpretationMut + LocalInterpretationMut + GenerativeInterpretation,
45 I::Resource: Clone + Resource,
46{
47 let mut result = Vec::new();
48
49 let i = value.interpretation(interpretation);
50 let subject = InterpretationDomain.subject(interpretation, i)?;
51
52 value.visit_subject(QuadPropertiesSerializer {
53 interpretation,
54 domain: &mut InterpretationDomain,
55 graph,
56 subject: SubjectOrObject::Subject(&subject),
57 result: &mut result,
58 })?;
59
60 Ok((subject, result))
61}
62
63pub fn to_interpreted_graph_quads<I>(
66 interpretation: &mut I,
67 value: &(impl LinkedDataGraph<I> + LinkedDataResource<I>),
68) -> Result<(I::Resource, Vec<InterpretedQuad<I>>), IntoQuadsError>
69where
70 I: Interpretation + InterpretationMut + LocalInterpretationMut + GenerativeInterpretation,
71 I::Resource: Clone + Resource,
72{
73 let mut result = Vec::new();
74
75 let i = value.interpretation(interpretation);
76 let graph = InterpretationDomain.graph(interpretation, i)?;
77
78 value.visit_graph(QuadGraphSerializer {
79 interpretation,
80 domain: &mut InterpretationDomain,
81 graph: Some(&graph),
82 result: &mut result,
83 })?;
84
85 Ok((graph, result))
86}
87
88pub fn to_lexical_quads_with<I>(
91 interpretation: &mut I,
92 value: &impl LinkedData<I>,
93) -> Result<Vec<RdfQuad>, IntoQuadsError>
94where
95 I: Interpretation
96 + InterpretationMut
97 + ReverseInterpretation
98 + ReverseLocalInterpretation
99 + GenerativeInterpretation,
100{
101 let mut domain = LexicalDomain;
102
103 value.visit(QuadSerializer {
104 interpretation,
105 domain: &mut domain,
106 result: Vec::new(),
107 })
108}
109
110pub fn to_lexical_subject_quads_with<I>(
113 interpretation: &mut I,
114 graph: Option<&Id>,
115 value: &(impl LinkedDataSubject<I> + LinkedDataResource<I>),
116) -> Result<(Id, Vec<RdfQuad>), IntoQuadsError>
117where
118 I: Interpretation
119 + InterpretationMut
120 + ReverseInterpretation
121 + ReverseLocalInterpretation
122 + GenerativeInterpretation,
123 I::Resource: Clone,
124{
125 let mut result = Vec::new();
126
127 let i = value.interpretation(interpretation);
128 let subject = LexicalDomain.subject(interpretation, i)?;
129
130 value.visit_subject(QuadPropertiesSerializer {
131 interpretation,
132 domain: &mut LexicalDomain,
133 graph,
134 subject: SubjectOrObject::Subject(&subject),
135 result: &mut result,
136 })?;
137
138 Ok((subject, result))
139}
140
141pub fn to_lexical_quads<G: LocalGenerator>(
144 generator: G,
145 value: &impl LinkedData<LocalGeneratorInterpretation<G>>,
146) -> Result<Vec<RdfQuad>, IntoQuadsError> {
147 let mut interpretation = LocalGeneratorInterpretation::new(generator);
148 to_lexical_quads_with(&mut interpretation, value)
149}
150
151pub fn to_lexical_subject_quads<G: LocalGenerator>(
154 generator: G,
155 graph: Option<&Id>,
156 value: &(
157 impl LinkedDataSubject<LocalGeneratorInterpretation<G>>
158 + LinkedDataResource<LocalGeneratorInterpretation<G>>
159 ),
160) -> Result<(Id, Vec<RdfQuad>), IntoQuadsError> {
161 let mut interpretation = LocalGeneratorInterpretation::new(generator);
162 to_lexical_subject_quads_with(&mut interpretation, graph, value)
163}
164
165pub fn to_quads_with<I>(
169 interpretation: &mut I,
170 value: &impl LinkedData<I>,
171) -> Result<Vec<RdfQuad>, IntoQuadsError>
172where
173 I: Interpretation
174 + InterpretationMut
175 + ReverseInterpretation
176 + ReverseLocalInterpretation
177 + GenerativeInterpretation,
178{
179 to_lexical_quads_with(interpretation, value)
180}
181
182pub fn to_quads<G: LocalGenerator>(
187 generator: G,
188 value: &impl LinkedData<LocalGeneratorInterpretation<G>>,
189) -> Result<Vec<RdfQuad>, IntoQuadsError> {
190 to_lexical_quads(generator, value)
191}
192
193#[derive(Debug, thiserror::Error)]
194pub enum IntoQuadsError {
196 #[error("invalid graph label")]
197 Graph,
199
200 #[error("invalid subject")]
201 Subject,
203
204 #[error("invalid predicate")]
205 Predicate,
207
208 #[error("missing lexical representation")]
209 MissingLexicalRepresentation,
211}
212
213trait Domain<I: Interpretation> {
214 type Subject: Clone + IsSubject + IsGraph;
215 type Predicate: Clone + IsPredicate;
216 type Object: IsObject;
217 type ObjectRef<'a>: Copy
218 where
219 I::Resource: 'a,
220 Self: 'a;
221
222 fn subject(
223 &mut self,
224 interpretation: &mut I,
225 value: ResourceInterpretation<I>,
226 ) -> Result<Self::Subject, IntoQuadsError>;
227
228 fn predicate(
229 &mut self,
230 interpretation: &mut I,
231 value: ResourceInterpretation<I>,
232 ) -> Result<Self::Predicate, IntoQuadsError>;
233
234 fn object(
235 &mut self,
236 interpretation: &mut I,
237 value: ResourceInterpretation<I>,
238 ) -> Result<Self::Object, IntoQuadsError>;
239
240 fn graph(
241 &mut self,
242 interpretation: &mut I,
243 value: ResourceInterpretation<I>,
244 ) -> Result<Self::Subject, IntoQuadsError>;
245
246 fn object_as_subject(&self, object: &Self::Object) -> Result<Self::Subject, IntoQuadsError>;
247
248 fn subject_as_object<'a>(
249 &self,
250 subject: &'a Self::Subject,
251 ) -> Result<Self::ObjectRef<'a>, IntoQuadsError>
252 where
253 I::Resource: 'a;
254
255 fn object_as_ref<'a>(object: &'a Self::Object) -> Self::ObjectRef<'a>
256 where
257 I::Resource: 'a;
258
259 fn cloned_object_ref<'a>(object_ref: Self::ObjectRef<'a>) -> Self::Object
260 where
261 I::Resource: 'a;
262}
263
264type DomainQuad<I, D> = Quad<
265 <D as Domain<I>>::Subject,
266 <D as Domain<I>>::Predicate,
267 <D as Domain<I>>::Object,
268 <D as Domain<I>>::Subject,
269>;
270
271struct InterpretationDomain;
272
273#[allow(clippy::type_complexity)]
274fn resource_to_local_term<I>(
275 interpretation: &I,
276 r: &I::Resource,
277) -> Result<LocalTerm, IntoQuadsError>
278where
279 I: ReverseInterpretation + ReverseLocalInterpretation,
280{
281 if let Some(iri) = interpretation.iris_of(r).next() {
282 return Ok(LocalTerm::iri(iri.into_owned()));
283 }
284
285 if let Some(lit) = interpretation.literals_of(r).next() {
286 return Ok(LocalTerm::literal(lit.into_owned()));
287 }
288
289 if let Some(blank_id) = interpretation.blank_ids_of(r).next() {
290 return Ok(LocalTerm::BlankId(blank_id.into_owned()));
291 }
292
293 Err(IntoQuadsError::MissingLexicalRepresentation)
294}
295
296fn resource_to_id<I>(interpretation: &I, r: &I::Resource) -> Result<Id, IntoQuadsError>
297where
298 I: ReverseInterpretation + ReverseLocalInterpretation,
299{
300 if let Some(iri) = interpretation.iris_of(r).next() {
301 return Ok(Id::Iri(iri.into_owned()));
302 }
303
304 if let Some(blank_id) = interpretation.blank_ids_of(r).next() {
305 return Ok(Id::BlankId(blank_id.into_owned()));
306 }
307
308 Err(IntoQuadsError::MissingLexicalRepresentation)
309}
310
311fn cow_term_into_id(t: CowRdfTerm<'_>) -> Option<Id> {
312 let owned = t.into_owned();
313 owned.into_id()
314}
315
316fn cow_term_into_iri(t: CowRdfTerm<'_>) -> Option<IriBuf> {
317 match t.into_owned() {
318 OwnedRdfTerm::Iri(i) => Some(i),
319 _ => None,
320 }
321}
322
323impl<I> Domain<I> for InterpretationDomain
324where
325 I: Interpretation + InterpretationMut + LocalInterpretationMut + GenerativeInterpretation,
326 I::Resource: Clone + Resource,
327{
328 type Subject = I::Resource;
329 type Predicate = I::Resource;
330 type Object = I::Resource;
331 type ObjectRef<'a>
332 = &'a I::Resource
333 where
334 I::Resource: 'a;
335
336 fn subject(
337 &mut self,
338 interpretation: &mut I,
339 value: ResourceInterpretation<I>,
340 ) -> Result<Self::Subject, IntoQuadsError> {
341 match value {
342 ResourceInterpretation::Interpreted(r) => Ok(r.clone()),
343 ResourceInterpretation::Uninterpreted(u) => match u {
344 Some(t) => match t.into_owned() {
345 OwnedRdfTerm::Iri(i) => {
346 Ok(interpretation.insert_iri(std::borrow::Cow::Owned(i)))
347 }
348 OwnedRdfTerm::BlankId(b) => {
349 Ok(interpretation.insert_blank_id(std::borrow::Cow::Owned(b)))
350 }
351 OwnedRdfTerm::Literal(_) => Err(IntoQuadsError::Subject),
352 },
353 None => Ok(interpretation.new_resource()),
354 },
355 }
356 }
357
358 fn predicate(
359 &mut self,
360 interpretation: &mut I,
361 value: ResourceInterpretation<I>,
362 ) -> Result<Self::Predicate, IntoQuadsError> {
363 match value {
364 ResourceInterpretation::Interpreted(r) => Ok(r.clone()),
365 ResourceInterpretation::Uninterpreted(u) => match u {
366 Some(t) => match t.into_owned() {
367 OwnedRdfTerm::Iri(i) => {
368 Ok(interpretation.insert_iri(std::borrow::Cow::Owned(i)))
369 }
370 _ => Err(IntoQuadsError::Predicate),
371 },
372 None => Err(IntoQuadsError::Predicate),
373 },
374 }
375 }
376
377 fn object(
378 &mut self,
379 interpretation: &mut I,
380 value: ResourceInterpretation<I>,
381 ) -> Result<Self::Object, IntoQuadsError> {
382 match value {
383 ResourceInterpretation::Interpreted(r) => Ok(r.clone()),
384 ResourceInterpretation::Uninterpreted(u) => match u {
385 Some(t) => match t.into_owned() {
386 OwnedRdfTerm::Iri(i) => {
387 Ok(interpretation.insert_iri(std::borrow::Cow::Owned(i)))
388 }
389 OwnedRdfTerm::BlankId(b) => {
390 Ok(interpretation.insert_blank_id(std::borrow::Cow::Owned(b)))
391 }
392 OwnedRdfTerm::Literal(l) => Ok(l.embed_into(interpretation)),
393 },
394 None => Ok(interpretation.new_resource()),
395 },
396 }
397 }
398
399 fn graph(
400 &mut self,
401 interpretation: &mut I,
402 value: ResourceInterpretation<I>,
403 ) -> Result<Self::Subject, IntoQuadsError> {
404 match value {
405 ResourceInterpretation::Interpreted(r) => Ok(r.clone()),
406 ResourceInterpretation::Uninterpreted(u) => match u {
407 Some(t) => match t.into_owned() {
408 OwnedRdfTerm::Iri(i) => {
409 Ok(interpretation.insert_iri(std::borrow::Cow::Owned(i)))
410 }
411 OwnedRdfTerm::BlankId(b) => {
412 Ok(interpretation.insert_blank_id(std::borrow::Cow::Owned(b)))
413 }
414 OwnedRdfTerm::Literal(_) => Err(IntoQuadsError::Graph),
415 },
416 None => Ok(interpretation.new_resource()),
417 },
418 }
419 }
420
421 fn object_as_subject(&self, object: &Self::Object) -> Result<Self::Subject, IntoQuadsError> {
422 Ok(object.clone())
423 }
424
425 fn subject_as_object<'a>(
426 &self,
427 subject: &'a Self::Subject,
428 ) -> Result<Self::ObjectRef<'a>, IntoQuadsError>
429 where
430 I::Resource: 'a,
431 {
432 Ok(subject)
433 }
434
435 fn object_as_ref<'a>(object: &'a Self::Object) -> Self::ObjectRef<'a>
436 where
437 I::Resource: 'a,
438 {
439 object
440 }
441
442 fn cloned_object_ref<'a>(object_ref: Self::ObjectRef<'a>) -> Self::Object
443 where
444 I::Resource: 'a,
445 {
446 object_ref.clone()
447 }
448}
449
450struct LexicalDomain;
451
452fn lexical_term_into_local(t: CowRdfTerm<'_>) -> LocalTerm {
453 match t.into_owned() {
454 OwnedRdfTerm::Iri(i) => LocalTerm::iri(i),
455 OwnedRdfTerm::BlankId(b) => LocalTerm::BlankId(b),
456 OwnedRdfTerm::Literal(l) => LocalTerm::literal(l.into_lexical()),
457 }
458}
459
460impl<I> Domain<I> for LexicalDomain
461where
462 I: Interpretation
463 + InterpretationMut
464 + ReverseInterpretation
465 + ReverseLocalInterpretation
466 + GenerativeInterpretation,
467{
468 type Subject = Id;
469 type Predicate = IriBuf;
470 type Object = LocalTerm;
471 type ObjectRef<'a>
472 = LocalTermRefCopy<'a>
473 where
474 I::Resource: 'a;
475
476 fn subject(
477 &mut self,
478 interpretation: &mut I,
479 value: ResourceInterpretation<I>,
480 ) -> Result<Self::Subject, IntoQuadsError> {
481 match value {
482 ResourceInterpretation::Interpreted(r) => resource_to_id(interpretation, r),
483 ResourceInterpretation::Uninterpreted(u) => match u {
484 Some(t) => cow_term_into_id(t).ok_or(IntoQuadsError::Subject),
485 None => {
486 let r = interpretation.new_resource();
487 resource_to_id(interpretation, &r)
488 }
489 },
490 }
491 }
492
493 fn predicate(
494 &mut self,
495 interpretation: &mut I,
496 value: ResourceInterpretation<I>,
497 ) -> Result<Self::Predicate, IntoQuadsError> {
498 match value {
499 ResourceInterpretation::Interpreted(r) => match interpretation.iris_of(r).next() {
500 Some(iri) => Ok(iri.into_owned()),
501 None => Err(IntoQuadsError::Predicate),
502 },
503 ResourceInterpretation::Uninterpreted(u) => match u {
504 Some(t) => cow_term_into_iri(t).ok_or(IntoQuadsError::Predicate),
505 None => Err(IntoQuadsError::Predicate),
506 },
507 }
508 }
509
510 fn object(
511 &mut self,
512 interpretation: &mut I,
513 value: ResourceInterpretation<I>,
514 ) -> Result<Self::Object, IntoQuadsError> {
515 match value {
516 ResourceInterpretation::Interpreted(r) => resource_to_local_term(interpretation, r),
517 ResourceInterpretation::Uninterpreted(u) => match u {
518 Some(t) => Ok(lexical_term_into_local(t)),
519 None => {
520 let r = interpretation.new_resource();
521 resource_to_local_term(interpretation, &r)
522 }
523 },
524 }
525 }
526
527 fn graph(
528 &mut self,
529 interpretation: &mut I,
530 value: ResourceInterpretation<I>,
531 ) -> Result<Self::Subject, IntoQuadsError> {
532 match value {
533 ResourceInterpretation::Interpreted(r) => resource_to_id(interpretation, r),
534 ResourceInterpretation::Uninterpreted(u) => match u {
535 Some(t) => cow_term_into_id(t).ok_or(IntoQuadsError::Graph),
536 None => {
537 let r = interpretation.new_resource();
538 resource_to_id(interpretation, &r)
539 }
540 },
541 }
542 }
543
544 fn object_as_subject(&self, object: &Self::Object) -> Result<Self::Subject, IntoQuadsError> {
545 match object {
546 LocalTerm::BlankId(b) => Ok(Id::BlankId(b.clone())),
547 LocalTerm::Named(Term::Iri(i)) => Ok(Id::Iri(i.clone())),
548 _ => Err(IntoQuadsError::Subject),
549 }
550 }
551
552 fn subject_as_object<'a>(
553 &self,
554 subject: &'a Self::Subject,
555 ) -> Result<Self::ObjectRef<'a>, IntoQuadsError>
556 where
557 I::Resource: 'a,
558 {
559 Ok(LocalTermRefCopy::Id(subject))
560 }
561
562 fn object_as_ref<'a>(object: &'a Self::Object) -> Self::ObjectRef<'a>
563 where
564 I::Resource: 'a,
565 {
566 LocalTermRefCopy::Term(object)
567 }
568
569 fn cloned_object_ref<'a>(object_ref: Self::ObjectRef<'a>) -> Self::Object
570 where
571 I::Resource: 'a,
572 {
573 match object_ref {
574 LocalTermRefCopy::Id(id) => match id {
575 Id::Iri(i) => LocalTerm::iri(i.clone()),
576 Id::BlankId(b) => LocalTerm::BlankId(b.clone()),
577 },
578 LocalTermRefCopy::Term(t) => t.clone(),
579 }
580 }
581}
582
583#[derive(Clone, Copy)]
584enum LocalTermRefCopy<'a> {
585 Id(&'a Id),
586 Term(&'a LocalTerm),
587}
588
589struct QuadSerializer<'a, I: Interpretation, D: Domain<I>> {
591 interpretation: &'a mut I,
592 domain: &'a mut D,
593 result: Vec<DomainQuad<I, D>>,
594}
595
596impl<'a, I: Interpretation, D: Domain<I>> Visitor<I> for QuadSerializer<'a, I, D> {
597 type Ok = Vec<DomainQuad<I, D>>;
598 type Error = IntoQuadsError;
599
600 fn default_graph<T>(&mut self, value: &T) -> Result<(), Self::Error>
601 where
602 T: ?Sized + crate::LinkedDataGraph<I>,
603 {
604 let graph_serializer = QuadGraphSerializer {
605 interpretation: self.interpretation,
606 domain: self.domain,
607 result: &mut self.result,
608 graph: None,
609 };
610
611 value.visit_graph(graph_serializer)
612 }
613
614 fn named_graph<T>(&mut self, value: &T) -> Result<(), Self::Error>
615 where
616 T: ?Sized + LinkedDataResource<I> + crate::LinkedDataGraph<I>,
617 {
618 let i = value.interpretation(self.interpretation);
619 let graph = self.domain.graph(self.interpretation, i)?;
620
621 let graph_serializer = QuadGraphSerializer {
622 interpretation: self.interpretation,
623 domain: self.domain,
624 result: &mut self.result,
625 graph: Some(&graph),
626 };
627
628 value.visit_graph(graph_serializer)
629 }
630
631 fn end(self) -> Result<Self::Ok, Self::Error> {
632 Ok(self.result)
633 }
634}
635
636struct QuadGraphSerializer<'a, I: Interpretation, D: Domain<I>> {
637 interpretation: &'a mut I,
638 domain: &'a mut D,
639 result: &'a mut Vec<DomainQuad<I, D>>,
640 graph: Option<&'a D::Subject>,
641}
642
643impl<'a, I: Interpretation, D: Domain<I>> GraphVisitor<I> for QuadGraphSerializer<'a, I, D> {
644 type Ok = ();
645 type Error = IntoQuadsError;
646
647 fn subject<T>(&mut self, value: &T) -> Result<(), Self::Error>
648 where
649 T: ?Sized + LinkedDataResource<I> + crate::LinkedDataSubject<I>,
650 {
651 let i = value.interpretation(self.interpretation);
652 let term = self.domain.subject(self.interpretation, i)?;
653
654 let properties_serializer = QuadPropertiesSerializer {
655 interpretation: self.interpretation,
656 domain: self.domain,
657 result: self.result,
658 graph: self.graph,
659 subject: SubjectOrObject::Subject(&term),
660 };
661
662 value.visit_subject(properties_serializer)
663 }
664
665 fn end(self) -> Result<Self::Ok, Self::Error> {
666 Ok(())
667 }
668}
669
670struct QuadPropertiesSerializer<'a, I: Interpretation, D: Domain<I>> {
671 interpretation: &'a mut I,
672 domain: &'a mut D,
673 result: &'a mut Vec<DomainQuad<I, D>>,
674 graph: Option<&'a D::Subject>,
675 subject: SubjectOrObject<'a, I, D>,
676}
677
678#[derive(Educe)]
679#[educe(Clone, Copy)]
680enum SubjectOrObject<'a, I: Interpretation, D: Domain<I>> {
681 Subject(&'a D::Subject),
682 Object(&'a D::Object),
683}
684
685impl<'a, I: Interpretation, D: Domain<I>> SubjectOrObject<'a, I, D> {
686 fn into_subject(self, domain: &D) -> Result<std::borrow::Cow<'a, D::Subject>, IntoQuadsError>
687 where
688 D::Subject: Clone,
689 {
690 match self {
691 Self::Subject(s) => Ok(std::borrow::Cow::Borrowed(s)),
692 Self::Object(o) => domain.object_as_subject(o).map(std::borrow::Cow::Owned),
693 }
694 }
695
696 fn into_object(self, domain: &D) -> Result<D::ObjectRef<'a>, IntoQuadsError> {
697 match self {
698 Self::Subject(s) => domain.subject_as_object(s),
699 Self::Object(o) => Ok(D::object_as_ref(o)),
700 }
701 }
702}
703
704impl<'a, I: Interpretation, D: Domain<I>> SubjectVisitor<I> for QuadPropertiesSerializer<'a, I, D> {
705 type Ok = ();
706 type Error = IntoQuadsError;
707
708 fn predicate<L, T>(&mut self, predicate: &L, value: &T) -> Result<(), Self::Error>
709 where
710 L: ?Sized + LinkedDataResource<I>,
711 T: ?Sized + crate::LinkedDataPredicateObjects<I>,
712 {
713 let subject = self.subject.into_subject(self.domain)?;
714
715 let i = predicate.interpretation(self.interpretation);
716 let term = self.domain.predicate(self.interpretation, i)?;
717
718 let objects_serializer = ObjectsSerializer {
719 interpretation: self.interpretation,
720 domain: self.domain,
721 result: self.result,
722 graph: self.graph,
723 subject: subject.as_ref(),
724 predicate: term,
725 };
726
727 value.visit_objects(objects_serializer)
728 }
729
730 fn reverse_predicate<L, T>(&mut self, predicate: &L, subjects: &T) -> Result<(), Self::Error>
731 where
732 L: ?Sized + LinkedDataResource<I>,
733 T: ?Sized + crate::LinkedDataPredicateObjects<I>,
734 {
735 let object = self.subject.into_object(self.domain)?;
736
737 let i = predicate.interpretation(self.interpretation);
738 let term = self.domain.predicate(self.interpretation, i)?;
739
740 let subjects_serializer = ReversePredicateSerializer {
741 interpretation: self.interpretation,
742 domain: self.domain,
743 result: self.result,
744 graph: self.graph,
745 object,
746 predicate: term,
747 };
748
749 subjects.visit_objects(subjects_serializer)
750 }
751
752 fn graph<T>(&mut self, value: &T) -> Result<(), Self::Error>
753 where
754 T: ?Sized + LinkedDataGraph<I>,
755 {
756 let graph = self.subject.into_subject(self.domain)?;
757
758 let graph_serializer = QuadGraphSerializer {
759 interpretation: self.interpretation,
760 domain: self.domain,
761 result: self.result,
762 graph: Some(graph.as_ref()),
763 };
764
765 value.visit_graph(graph_serializer)
766 }
767
768 fn include<T>(&mut self, value: &T) -> Result<(), Self::Error>
769 where
770 T: ?Sized + LinkedDataResource<I> + LinkedDataSubject<I>,
771 {
772 let i = value.interpretation(self.interpretation);
773 let subject = self.domain.subject(self.interpretation, i)?;
774
775 value.visit_subject(QuadPropertiesSerializer {
776 interpretation: self.interpretation,
777 domain: self.domain,
778 graph: self.graph,
779 subject: SubjectOrObject::Subject(&subject),
780 result: self.result,
781 })?;
782
783 Ok(())
784 }
785
786 fn end(self) -> Result<Self::Ok, Self::Error> {
787 Ok(())
788 }
789}
790
791struct ObjectsSerializer<'a, I: Interpretation, D: Domain<I>> {
792 interpretation: &'a mut I,
793 domain: &'a mut D,
794 result: &'a mut Vec<DomainQuad<I, D>>,
795 graph: Option<&'a D::Subject>,
796 subject: &'a D::Subject,
797 predicate: D::Predicate,
798}
799
800impl<'a, I: Interpretation, D: Domain<I>> PredicateObjectsVisitor<I>
801 for ObjectsSerializer<'a, I, D>
802{
803 type Ok = ();
804 type Error = IntoQuadsError;
805
806 fn object<T>(&mut self, value: &T) -> Result<(), Self::Error>
807 where
808 T: ?Sized + LinkedDataResource<I> + crate::LinkedDataSubject<I>,
809 {
810 let i = value.interpretation(self.interpretation);
811 let term = self.domain.object(self.interpretation, i)?;
812 let subject_serializer = QuadPropertiesSerializer {
813 interpretation: self.interpretation,
814 domain: self.domain,
815 result: self.result,
816 graph: self.graph,
817 subject: SubjectOrObject::Object(&term),
818 };
819
820 value.visit_subject(subject_serializer)?;
821 self.result.push(Quad(
822 self.subject.clone(),
823 self.predicate.clone(),
824 term,
825 self.graph.cloned(),
826 ));
827 Ok(())
828 }
829
830 fn end(self) -> Result<Self::Ok, Self::Error> {
831 Ok(())
832 }
833}
834
835struct ReversePredicateSerializer<'a, I: Interpretation, D: Domain<I>> {
836 interpretation: &'a mut I,
837 domain: &'a mut D,
838 result: &'a mut Vec<DomainQuad<I, D>>,
839 graph: Option<&'a D::Subject>,
840 object: D::ObjectRef<'a>,
841 predicate: D::Predicate,
842}
843
844impl<'a, I: Interpretation, D: Domain<I>> PredicateObjectsVisitor<I>
845 for ReversePredicateSerializer<'a, I, D>
846{
847 type Ok = ();
848 type Error = IntoQuadsError;
849
850 fn object<T>(&mut self, value: &T) -> Result<(), Self::Error>
851 where
852 T: ?Sized + LinkedDataResource<I> + crate::LinkedDataSubject<I>,
853 {
854 let i = value.interpretation(self.interpretation);
855 let subject = self.domain.subject(self.interpretation, i)?;
856
857 let subject_serializer = QuadPropertiesSerializer {
858 interpretation: self.interpretation,
859 domain: self.domain,
860 result: self.result,
861 graph: self.graph,
862 subject: SubjectOrObject::Subject(&subject),
863 };
864
865 value.visit_subject(subject_serializer)?;
866 self.result.push(Quad(
867 subject,
868 self.predicate.clone(),
869 D::cloned_object_ref(self.object),
870 self.graph.cloned(),
871 ));
872 Ok(())
873 }
874
875 fn end(self) -> Result<Self::Ok, Self::Error> {
876 Ok(())
877 }
878}