linked-data 0.2.0

Linked-Data dateset serialization/deserialization traits
Documentation
use rdf_syntax::Term;

use crate::LinkedDataDeserializer;

pub struct FlattenDeserializer<'a, D, R = Term> {
	inner: D,
	resources: &'a mut Vec<R>,
	pending: Vec<R>,
}

impl<'a, R, D> FlattenDeserializer<'a, D, R> {
	pub fn new(inner: D, resources: &'a mut Vec<R>) -> Self
	where
		R: Clone,
	{
		let mut pending = resources.clone();
		pending.reverse();

		Self {
			inner,
			resources,
			pending,
		}
	}
}

impl<'a, R: Clone + Ord, D: LinkedDataDeserializer<R>> LinkedDataDeserializer<R>
	for FlattenDeserializer<'a, D, R>
{
	type Error = D::Error;

	fn interpret(&mut self, term: rdf_syntax::CowTerm) -> Result<R, Self::Error> {
		self.inner.interpret(term)
	}

	fn terms_of<'r>(
		&'r self,
		resource: &'r R,
	) -> Result<impl Iterator<Item = Result<rdf_syntax::CowTerm<'r>, Self::Error>>, Self::Error> {
		self.inner.terms_of(resource)
	}

	fn peek_resources<'b>(
		&'b self,
	) -> Result<impl Iterator<Item = Result<&'b R, Self::Error>>, Self::Error>
	where
		R: 'b,
	{
		Ok(self
			.pending
			.iter()
			.rev()
			.map(Ok)
			.chain(self.inner.peek_resources()?))
	}

	fn deserialize_resource(&mut self, resource: Option<R>) -> Result<Option<R>, Self::Error> {
		let pending_resource = self.pending.pop();

		match (pending_resource, resource) {
			(Some(a), Some(b)) => {
				if a == b {
					Ok(Some(a))
				} else {
					Err(crate::de::Error::unexpected_resource(&b))
				}
			}
			(Some(a), None) => Ok(Some(a)),
			(None, b) => Ok(self
				.inner
				.deserialize_resource(b)?
				.inspect(|b| self.resources.push(b.clone()))),
		}
	}

	fn deserialize_quad<'p>(
		&mut self,
		pattern: impl Into<rdf_syntax::pattern::LinearQuadPattern<&'p R>>,
	) -> Result<Option<rdf_syntax::Quad<R>>, Self::Error>
	where
		R: 'p,
	{
		self.inner.deserialize_quad(pattern)
	}

	fn peek_quads<'p>(
		&'p self,
		pattern: impl Into<rdf_syntax::pattern::LinearQuadPattern<&'p R>>,
	) -> Result<impl Iterator<Item = Result<rdf_syntax::Quad<&'p R>, Self::Error>>, Self::Error>
	where
		R: 'p,
	{
		self.inner.peek_quads(pattern)
	}
}