Skip to main content

linked_data/de/
flatten.rs

1use 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}