linked_data/de/
flatten.rs1use rdf_syntax::Term;
2
3use crate::LinkedDataDeserializer;
4
5pub struct FlattenDeserializer<'a, D, R = Term> {
6 inner: D,
7 resources: &'a mut Vec<R>,
8 pending: Vec<R>,
9}
10
11impl<'a, R, D> FlattenDeserializer<'a, D, R> {
12 pub fn new(inner: D, resources: &'a mut Vec<R>) -> Self
13 where
14 R: Clone,
15 {
16 let mut pending = resources.clone();
17 pending.reverse();
18
19 Self {
20 inner,
21 resources,
22 pending,
23 }
24 }
25}
26
27impl<'a, R: Clone + Ord, D: LinkedDataDeserializer<R>> LinkedDataDeserializer<R>
28 for FlattenDeserializer<'a, D, R>
29{
30 type Error = D::Error;
31
32 fn interpret(&mut self, term: rdf_syntax::CowTerm) -> Result<R, Self::Error> {
33 self.inner.interpret(term)
34 }
35
36 fn terms_of<'r>(
37 &'r self,
38 resource: &'r R,
39 ) -> Result<impl Iterator<Item = Result<rdf_syntax::CowTerm<'r>, Self::Error>>, Self::Error> {
40 self.inner.terms_of(resource)
41 }
42
43 fn peek_resources<'b>(
44 &'b self,
45 ) -> Result<impl Iterator<Item = Result<&'b R, Self::Error>>, Self::Error>
46 where
47 R: 'b,
48 {
49 Ok(self
50 .pending
51 .iter()
52 .rev()
53 .map(Ok)
54 .chain(self.inner.peek_resources()?))
55 }
56
57 fn deserialize_resource(&mut self, resource: Option<R>) -> Result<Option<R>, Self::Error> {
58 let pending_resource = self.pending.pop();
59
60 match (pending_resource, resource) {
61 (Some(a), Some(b)) => {
62 if a == b {
63 Ok(Some(a))
64 } else {
65 Err(crate::de::Error::unexpected_resource(&b))
66 }
67 }
68 (Some(a), None) => Ok(Some(a)),
69 (None, b) => Ok(self
70 .inner
71 .deserialize_resource(b)?
72 .inspect(|b| self.resources.push(b.clone()))),
73 }
74 }
75
76 fn deserialize_quad<'p>(
77 &mut self,
78 pattern: impl Into<rdf_syntax::pattern::LinearQuadPattern<&'p R>>,
79 ) -> Result<Option<rdf_syntax::Quad<R>>, Self::Error>
80 where
81 R: 'p,
82 {
83 self.inner.deserialize_quad(pattern)
84 }
85
86 fn peek_quads<'p>(
87 &'p self,
88 pattern: impl Into<rdf_syntax::pattern::LinearQuadPattern<&'p R>>,
89 ) -> Result<impl Iterator<Item = Result<rdf_syntax::Quad<&'p R>, Self::Error>>, Self::Error>
90 where
91 R: 'p,
92 {
93 self.inner.peek_quads(pattern)
94 }
95}