pub mod model {
use std::convert::{TryFrom, TryInto};
use std::error::Error;
use std::fmt;
pub use crate::model::*;
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash)]
pub struct Variable<'a> {
pub name: &'a str,
}
impl<'a> fmt::Display for Variable<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "?{}", self.name)
}
}
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub enum GeneralizedTerm<'a> {
NamedNode(NamedNode<'a>),
BlankNode(BlankNode<'a>),
Literal(Literal<'a>),
Variable(Variable<'a>),
}
impl<'a> From<NamedNode<'a>> for GeneralizedTerm<'a> {
fn from(other: NamedNode<'a>) -> GeneralizedTerm<'a> {
GeneralizedTerm::NamedNode(other)
}
}
impl<'a> From<BlankNode<'a>> for GeneralizedTerm<'a> {
fn from(other: BlankNode<'a>) -> GeneralizedTerm<'a> {
GeneralizedTerm::BlankNode(other)
}
}
impl<'a> From<Literal<'a>> for GeneralizedTerm<'a> {
fn from(other: Literal<'a>) -> GeneralizedTerm<'a> {
GeneralizedTerm::Literal(other)
}
}
impl<'a> From<Variable<'a>> for GeneralizedTerm<'a> {
fn from(other: Variable<'a>) -> GeneralizedTerm<'a> {
GeneralizedTerm::Variable(other)
}
}
impl<'a> From<NamedOrBlankNode<'a>> for GeneralizedTerm<'a> {
fn from(other: NamedOrBlankNode<'a>) -> GeneralizedTerm<'a> {
match other {
NamedOrBlankNode::NamedNode(inner) => GeneralizedTerm::NamedNode(inner),
NamedOrBlankNode::BlankNode(inner) => GeneralizedTerm::BlankNode(inner),
}
}
}
impl<'a> From<Term<'a>> for GeneralizedTerm<'a> {
fn from(other: Term<'a>) -> GeneralizedTerm<'a> {
match other {
Term::NamedNode(inner) => GeneralizedTerm::NamedNode(inner),
Term::BlankNode(inner) => GeneralizedTerm::BlankNode(inner),
Term::Literal(inner) => GeneralizedTerm::Literal(inner),
}
}
}
impl<'a> TryFrom<GeneralizedTerm<'a>> for NamedNode<'a> {
type Error = StrictRdfError;
fn try_from(other: GeneralizedTerm<'a>) -> Result<NamedNode<'a>, StrictRdfError> {
match other {
GeneralizedTerm::NamedNode(inner) => Ok(inner),
GeneralizedTerm::BlankNode(_) => Err(StrictRdfError {
message: "Blank node cannot be used as predicate",
}),
GeneralizedTerm::Literal(_) => Err(StrictRdfError {
message: "Literal cannot be used as predicate",
}),
GeneralizedTerm::Variable(_) => Err(StrictRdfError {
message: "Variable cannot be converted to Term",
}),
}
}
}
impl<'a> TryFrom<GeneralizedTerm<'a>> for NamedOrBlankNode<'a> {
type Error = StrictRdfError;
fn try_from(other: GeneralizedTerm<'a>) -> Result<NamedOrBlankNode<'a>, StrictRdfError> {
match other {
GeneralizedTerm::NamedNode(inner) => Ok(NamedOrBlankNode::NamedNode(inner)),
GeneralizedTerm::BlankNode(inner) => Ok(NamedOrBlankNode::BlankNode(inner)),
GeneralizedTerm::Literal(_) => Err(StrictRdfError {
message: "Literal cannot be used a subject",
}),
GeneralizedTerm::Variable(_) => Err(StrictRdfError {
message: "Variable cannot be converted to Term",
}),
}
}
}
impl<'a> TryFrom<GeneralizedTerm<'a>> for Term<'a> {
type Error = StrictRdfError;
fn try_from(other: GeneralizedTerm<'a>) -> Result<Term<'a>, StrictRdfError> {
match other {
GeneralizedTerm::NamedNode(inner) => Ok(Term::NamedNode(inner)),
GeneralizedTerm::BlankNode(inner) => Ok(Term::BlankNode(inner)),
GeneralizedTerm::Literal(inner) => Ok(Term::Literal(inner)),
GeneralizedTerm::Variable(_) => Err(StrictRdfError {
message: "Variable cannot be converted to Term",
}),
}
}
}
impl<'a> fmt::Display for GeneralizedTerm<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
GeneralizedTerm::NamedNode(node) => node.fmt(f),
GeneralizedTerm::BlankNode(node) => node.fmt(f),
GeneralizedTerm::Literal(literal) => literal.fmt(f),
GeneralizedTerm::Variable(variable) => variable.fmt(f),
}
}
}
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct GeneralizedQuad<'a> {
pub subject: GeneralizedTerm<'a>,
pub predicate: GeneralizedTerm<'a>,
pub object: GeneralizedTerm<'a>,
pub graph_name: Option<GeneralizedTerm<'a>>,
}
impl<'a> From<Quad<'a>> for GeneralizedQuad<'a> {
fn from(other: Quad<'a>) -> GeneralizedQuad<'a> {
GeneralizedQuad {
subject: other.subject.into(),
predicate: other.predicate.into(),
object: other.object.into(),
graph_name: other.graph_name.map(GeneralizedTerm::from),
}
}
}
impl<'a> TryFrom<GeneralizedQuad<'a>> for Quad<'a> {
type Error = StrictRdfError;
fn try_from(other: GeneralizedQuad<'a>) -> Result<Quad<'a>, StrictRdfError> {
Ok(Quad {
subject: other.subject.try_into()?,
predicate: other.predicate.try_into()?,
object: other.object.try_into()?,
graph_name: other
.graph_name
.map(GeneralizedTerm::try_into)
.transpose()?,
})
}
}
impl<'a> TryFrom<GeneralizedQuad<'a>> for Triple<'a> {
type Error = StrictRdfError;
fn try_from(other: GeneralizedQuad<'a>) -> Result<Triple<'a>, StrictRdfError> {
match other.graph_name {
Some(_) => Err(StrictRdfError {
message: "Quad in named graph cannot be converted to Triple",
}),
None => Ok(Triple {
subject: other.subject.try_into()?,
predicate: other.predicate.try_into()?,
object: other.object.try_into()?,
}),
}
}
}
impl<'a> fmt::Display for GeneralizedQuad<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(graph_name) = self.graph_name {
write!(f, "GRAPH {} {{ ", graph_name)?;
}
write!(f, "{} {} {} .", self.subject, self.predicate, self.object)?;
if self.graph_name.is_some() {
write!(f, "}}")?;
}
Ok(())
}
}
#[derive(Debug, Clone, Copy)]
pub struct StrictRdfError {
message: &'static str,
}
impl<'a> fmt::Display for StrictRdfError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.message.fmt(f)
}
}
impl Error for StrictRdfError {}
}
pub mod parser {
use super::model::GeneralizedQuad;
use std::error::Error;
pub trait GeneralizedQuadsParser {
type Error: Error;
fn parse_all<E: From<Self::Error>>(
&mut self,
on_quad: &mut impl FnMut(GeneralizedQuad<'_>) -> Result<(), E>,
) -> Result<(), E> {
while !self.is_end() {
self.parse_step(on_quad)?
}
Ok(())
}
fn parse_step<E: From<Self::Error>>(
&mut self,
on_quad: &mut impl FnMut(GeneralizedQuad<'_>) -> Result<(), E>,
) -> Result<(), E>;
fn is_end(&self) -> bool;
fn into_iter<T, E, F>(
self,
convert_quad: F,
) -> GeneralizedQuadsParserIterator<T, E, F, Self>
where
E: From<Self::Error>,
F: FnMut(GeneralizedQuad<'_>) -> Result<T, E>,
Self: Sized,
{
GeneralizedQuadsParserIterator {
parser: self,
buffer: Vec::default(),
convert_quad,
}
}
}
pub struct GeneralizedQuadsParserIterator<
T,
E: From<P::Error>,
F: FnMut(GeneralizedQuad<'_>) -> Result<T, E>,
P: GeneralizedQuadsParser,
> {
parser: P,
buffer: Vec<T>,
convert_quad: F,
}
impl<T, E, F, P> Iterator for GeneralizedQuadsParserIterator<T, E, F, P>
where
E: From<P::Error>,
F: FnMut(GeneralizedQuad<'_>) -> Result<T, E>,
P: GeneralizedQuadsParser + Sized,
{
type Item = Result<T, E>;
fn next(&mut self) -> Option<Result<T, E>> {
loop {
if let Some(r) = self.buffer.pop() {
return Some(Ok(r));
}
if self.parser.is_end() {
return None;
}
let buffer = &mut self.buffer;
let convert_quad = &mut self.convert_quad;
if let Err(e) = self
.parser
.parse_step(&mut |q| convert_quad(q).map(|q| buffer.push(q)))
{
return Some(Err(e));
}
}
}
}
}