parent
fd3def2daf
commit
d617e72550
@ -0,0 +1,210 @@ |
|||||||
|
use crate::model::*; |
||||||
|
use crate::sparql::xml_results::{read_xml_results, write_xml_results}; |
||||||
|
use crate::Result; |
||||||
|
use failure::format_err; |
||||||
|
use std::fmt; |
||||||
|
use std::io::{BufRead, Write}; |
||||||
|
use uuid::Uuid; |
||||||
|
|
||||||
|
/// Results of a [SPARQL query](https://www.w3.org/TR/sparql11-query/)
|
||||||
|
pub enum QueryResult<'a> { |
||||||
|
/// Results of a [SELECT](https://www.w3.org/TR/sparql11-query/#select) query
|
||||||
|
Bindings(BindingsIterator<'a>), |
||||||
|
/// Result of a [ASK](https://www.w3.org/TR/sparql11-query/#ask) query
|
||||||
|
Boolean(bool), |
||||||
|
/// Results of a [CONSTRUCT](https://www.w3.org/TR/sparql11-query/#construct) or [DESCRIBE](https://www.w3.org/TR/sparql11-query/#describe) query
|
||||||
|
Graph(Box<dyn Iterator<Item = Result<Triple>> + 'a>), |
||||||
|
} |
||||||
|
|
||||||
|
impl<'a> QueryResult<'a> { |
||||||
|
pub fn read( |
||||||
|
reader: impl BufRead + 'static, |
||||||
|
syntax: QueryResultSyntax, |
||||||
|
) -> Result<QueryResult<'static>> { |
||||||
|
match syntax { |
||||||
|
QueryResultSyntax::Xml => read_xml_results(reader), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn write<W: Write>(self, writer: W, syntax: QueryResultSyntax) -> Result<W> { |
||||||
|
match syntax { |
||||||
|
QueryResultSyntax::Xml => write_xml_results(self, writer), |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// [SPARQL query](https://www.w3.org/TR/sparql11-query/) serialization formats
|
||||||
|
#[derive(Eq, PartialEq, Debug, Clone, Hash)] |
||||||
|
pub enum QueryResultSyntax { |
||||||
|
/// [SPARQL Query Results XML Format](http://www.w3.org/TR/rdf-sparql-XMLres/)
|
||||||
|
Xml, |
||||||
|
} |
||||||
|
|
||||||
|
/// An iterator over results bindings
|
||||||
|
pub struct BindingsIterator<'a> { |
||||||
|
variables: Vec<Variable>, |
||||||
|
iter: Box<dyn Iterator<Item = Result<Vec<Option<Term>>>> + 'a>, |
||||||
|
} |
||||||
|
|
||||||
|
impl<'a> BindingsIterator<'a> { |
||||||
|
pub(crate) fn new( |
||||||
|
variables: Vec<Variable>, |
||||||
|
iter: Box<dyn Iterator<Item = Result<Vec<Option<Term>>>> + 'a>, |
||||||
|
) -> Self { |
||||||
|
Self { variables, iter } |
||||||
|
} |
||||||
|
|
||||||
|
pub fn variables(&self) -> &[Variable] { |
||||||
|
&*self.variables |
||||||
|
} |
||||||
|
|
||||||
|
pub fn into_values_iter(self) -> Box<dyn Iterator<Item = Result<Vec<Option<Term>>>> + 'a> { |
||||||
|
self.iter |
||||||
|
} |
||||||
|
|
||||||
|
pub fn destruct( |
||||||
|
self, |
||||||
|
) -> ( |
||||||
|
Vec<Variable>, |
||||||
|
Box<dyn Iterator<Item = Result<Vec<Option<Term>>>> + 'a>, |
||||||
|
) { |
||||||
|
(self.variables, self.iter) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// A SPARQL query variable
|
||||||
|
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)] |
||||||
|
pub enum Variable { |
||||||
|
Variable { name: String }, |
||||||
|
BlankNode { id: Uuid }, |
||||||
|
Internal { id: Uuid }, |
||||||
|
} |
||||||
|
|
||||||
|
impl Variable { |
||||||
|
pub fn new(name: impl Into<String>) -> Self { |
||||||
|
Variable::Variable { name: name.into() } |
||||||
|
} |
||||||
|
|
||||||
|
pub fn has_name(&self) -> bool { |
||||||
|
match self { |
||||||
|
Variable::Variable { .. } => true, |
||||||
|
_ => false, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn name(&self) -> Result<&str> { |
||||||
|
match self { |
||||||
|
Variable::Variable { name } => Ok(name), |
||||||
|
_ => Err(format_err!("The variable {} has no name", self)), |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl fmt::Display for Variable { |
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
||||||
|
match self { |
||||||
|
Variable::Variable { name } => write!(f, "?{}", name), |
||||||
|
Variable::BlankNode { id } => write!(f, "_:{}", id.to_simple()), |
||||||
|
Variable::Internal { id } => write!(f, "?{}", id.to_simple()), |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl Default for Variable { |
||||||
|
fn default() -> Self { |
||||||
|
Variable::Internal { id: Uuid::new_v4() } |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl From<BlankNode> for Variable { |
||||||
|
fn from(blank_node: BlankNode) -> Self { |
||||||
|
Variable::BlankNode { |
||||||
|
id: *blank_node.as_uuid(), |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)] |
||||||
|
pub enum NamedNodeOrVariable { |
||||||
|
NamedNode(NamedNode), |
||||||
|
Variable(Variable), |
||||||
|
} |
||||||
|
|
||||||
|
impl fmt::Display for NamedNodeOrVariable { |
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
||||||
|
match self { |
||||||
|
NamedNodeOrVariable::NamedNode(node) => write!(f, "{}", node), |
||||||
|
NamedNodeOrVariable::Variable(var) => write!(f, "{}", var), |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl From<NamedNode> for NamedNodeOrVariable { |
||||||
|
fn from(node: NamedNode) -> Self { |
||||||
|
NamedNodeOrVariable::NamedNode(node) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl From<Variable> for NamedNodeOrVariable { |
||||||
|
fn from(var: Variable) -> Self { |
||||||
|
NamedNodeOrVariable::Variable(var) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)] |
||||||
|
pub enum TermOrVariable { |
||||||
|
Term(Term), |
||||||
|
Variable(Variable), |
||||||
|
} |
||||||
|
|
||||||
|
impl fmt::Display for TermOrVariable { |
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
||||||
|
match self { |
||||||
|
TermOrVariable::Term(term) => write!(f, "{}", term), |
||||||
|
TermOrVariable::Variable(var) => write!(f, "{}", var), |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl From<NamedNode> for TermOrVariable { |
||||||
|
fn from(node: NamedNode) -> Self { |
||||||
|
TermOrVariable::Term(node.into()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl From<BlankNode> for TermOrVariable { |
||||||
|
fn from(node: BlankNode) -> Self { |
||||||
|
TermOrVariable::Variable(node.into()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl From<Literal> for TermOrVariable { |
||||||
|
fn from(literal: Literal) -> Self { |
||||||
|
TermOrVariable::Term(literal.into()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl From<Variable> for TermOrVariable { |
||||||
|
fn from(var: Variable) -> Self { |
||||||
|
TermOrVariable::Variable(var) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl From<Term> for TermOrVariable { |
||||||
|
fn from(term: Term) -> Self { |
||||||
|
match term { |
||||||
|
Term::NamedNode(node) => TermOrVariable::Term(node.into()), |
||||||
|
Term::BlankNode(node) => TermOrVariable::Variable(node.into()), |
||||||
|
Term::Literal(literal) => TermOrVariable::Term(literal.into()), |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl From<NamedNodeOrVariable> for TermOrVariable { |
||||||
|
fn from(element: NamedNodeOrVariable) -> Self { |
||||||
|
match element { |
||||||
|
NamedNodeOrVariable::NamedNode(node) => TermOrVariable::Term(node.into()), |
||||||
|
NamedNodeOrVariable::Variable(var) => TermOrVariable::Variable(var), |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue