Moves spargebra debug to regular debug

... ands adds to_sse() methods
in order to be less surprising
pull/171/head
Tpt 3 years ago
parent 9952f1256d
commit 969bb69fab
  1. 430
      spargebra/src/algebra.rs
  2. 2
      spargebra/src/parser.rs
  3. 46
      spargebra/src/query.rs
  4. 378
      spargebra/src/term.rs
  5. 80
      spargebra/src/update.rs

@ -5,7 +5,7 @@ use crate::term::*;
use std::fmt; use std::fmt;
/// A [property path expression](https://www.w3.org/TR/sparql11-query/#defn_PropertyPathExpr) /// A [property path expression](https://www.w3.org/TR/sparql11-query/#defn_PropertyPathExpr)
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum PropertyPathExpression { pub enum PropertyPathExpression {
NamedNode(NamedNode), NamedNode(NamedNode),
Reverse(Box<Self>), Reverse(Box<Self>),
@ -17,20 +17,50 @@ pub enum PropertyPathExpression {
NegatedPropertySet(Vec<NamedNode>), NegatedPropertySet(Vec<NamedNode>),
} }
impl fmt::Debug for PropertyPathExpression { impl PropertyPathExpression {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
match self { match self {
Self::NamedNode(p) => p.fmt(f), Self::NamedNode(p) => p.fmt_sse(f),
Self::Reverse(p) => write!(f, "(reverse {:?})", p), Self::Reverse(p) => {
Self::Alternative(a, b) => write!(f, "(alt {:?} {:?})", a, b), write!(f, "(reverse ")?;
Self::Sequence(a, b) => write!(f, "(seq {:?} {:?})", a, b), p.fmt_sse(f)?;
Self::ZeroOrMore(p) => write!(f, "(path* {:?})", p), write!(f, ")")
Self::OneOrMore(p) => write!(f, "(path+ {:?})", p), }
Self::ZeroOrOne(p) => write!(f, "(path? {:?})", p), Self::Alternative(a, b) => {
write!(f, "(alt ")?;
a.fmt_sse(f)?;
write!(f, " ")?;
b.fmt_sse(f)?;
write!(f, ")")
}
Self::Sequence(a, b) => {
write!(f, "(seq ")?;
a.fmt_sse(f)?;
write!(f, " ")?;
b.fmt_sse(f)?;
write!(f, ")")
}
Self::ZeroOrMore(p) => {
write!(f, "(path* ")?;
p.fmt_sse(f)?;
write!(f, ")")
}
Self::OneOrMore(p) => {
write!(f, "(path+ ")?;
p.fmt_sse(f)?;
write!(f, ")")
}
Self::ZeroOrOne(p) => {
write!(f, "(path? ")?;
p.fmt_sse(f)?;
write!(f, ")")
}
Self::NegatedPropertySet(p) => { Self::NegatedPropertySet(p) => {
write!(f, "(notoneof ")?; write!(f, "(notoneof")?;
for p in p { for p in p {
write!(f, " {:?}", p)?; write!(f, " ")?;
p.fmt_sse(f)?;
} }
write!(f, ")") write!(f, ")")
} }
@ -69,7 +99,7 @@ impl From<NamedNode> for PropertyPathExpression {
} }
/// An [expression](https://www.w3.org/TR/sparql11-query/#expressions) /// An [expression](https://www.w3.org/TR/sparql11-query/#expressions)
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum Expression { pub enum Expression {
NamedNode(NamedNode), NamedNode(NamedNode),
Literal(Literal), Literal(Literal),
@ -116,48 +146,70 @@ pub enum Expression {
FunctionCall(Function, Vec<Self>), FunctionCall(Function, Vec<Self>),
} }
impl fmt::Debug for Expression { impl Expression {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
match self { match self {
Self::NamedNode(node) => node.fmt(f), Self::NamedNode(node) => node.fmt_sse(f),
Self::Literal(l) => l.fmt(f), Self::Literal(l) => l.fmt_sse(f),
Self::Variable(var) => var.fmt(f), Self::Variable(var) => var.fmt_sse(f),
Self::Or(a, b) => write!(f, "(|| {:?} {:?})", a, b), Self::Or(a, b) => fmt_sse_binary_expression(f, "||", a, b),
Self::And(a, b) => write!(f, "(&& {:?} {:?})", a, b), Self::And(a, b) => fmt_sse_binary_expression(f, "&&", a, b),
Self::Equal(a, b) => write!(f, "(= {:?} {:?})", a, b), Self::Equal(a, b) => fmt_sse_binary_expression(f, "=", a, b),
Self::SameTerm(a, b) => write!(f, "(sameTerm {:?} {:?})", a, b), Self::SameTerm(a, b) => fmt_sse_binary_expression(f, "sameTerm", a, b),
Self::Greater(a, b) => write!(f, "(> {:?} {:?})", a, b), Self::Greater(a, b) => fmt_sse_binary_expression(f, ">", a, b),
Self::GreaterOrEqual(a, b) => write!(f, "(>= {:?} {:?})", a, b), Self::GreaterOrEqual(a, b) => fmt_sse_binary_expression(f, ">=", a, b),
Self::Less(a, b) => write!(f, "(< {:?} {:?})", a, b), Self::Less(a, b) => fmt_sse_binary_expression(f, "<", a, b),
Self::LessOrEqual(a, b) => write!(f, "(<= {:?} {:?})", a, b), Self::LessOrEqual(a, b) => fmt_sse_binary_expression(f, "<=", a, b),
Self::In(a, b) => { Self::In(a, b) => {
write!(f, "(in {:?}", a)?; write!(f, "(in ")?;
a.fmt_sse(f)?;
for p in b { for p in b {
write!(f, " {:?}", p)?; write!(f, " ")?;
p.fmt_sse(f)?;
} }
write!(f, ")") write!(f, ")")
} }
Self::Add(a, b) => write!(f, "(+ {:?} {:?})", a, b), Self::Add(a, b) => fmt_sse_binary_expression(f, "+", a, b),
Self::Subtract(a, b) => write!(f, "(- {:?} {:?})", a, b), Self::Subtract(a, b) => fmt_sse_binary_expression(f, "-", a, b),
Self::Multiply(a, b) => write!(f, "(* {:?} {:?})", a, b), Self::Multiply(a, b) => fmt_sse_binary_expression(f, "*", a, b),
Self::Divide(a, b) => write!(f, "(/ {:?} {:?})", a, b), Self::Divide(a, b) => fmt_sse_binary_expression(f, "/", a, b),
Self::UnaryPlus(e) => write!(f, "(+ {:?})", e), Self::UnaryPlus(e) => fmt_sse_unary_expression(f, "+", e),
Self::UnaryMinus(e) => write!(f, "(- {:?})", e), Self::UnaryMinus(e) => fmt_sse_unary_expression(f, "-", e),
Self::Not(e) => write!(f, "(! {:?})", e), Self::Not(e) => fmt_sse_unary_expression(f, "!", e),
Self::FunctionCall(function, parameters) => { Self::FunctionCall(function, parameters) => {
write!(f, "({:?}", function)?; write!(f, "( ")?;
function.fmt_sse(f)?;
for p in parameters { for p in parameters {
write!(f, " {:?}", p)?; write!(f, " ")?;
p.fmt_sse(f)?;
} }
write!(f, ")") write!(f, ")")
} }
Self::Exists(p) => write!(f, "(exists {:?})", p), Self::Exists(p) => {
Self::Bound(v) => write!(f, "(bound {:?})", v), write!(f, "(exists ")?;
Self::If(a, b, c) => write!(f, "(if {:?} {:?} {:?})", a, b, c), p.fmt_sse(f)?;
write!(f, ")")
}
Self::Bound(v) => {
write!(f, "(bound ")?;
v.fmt_sse(f)?;
write!(f, ")")
}
Self::If(a, b, c) => {
write!(f, "(if ")?;
a.fmt_sse(f)?;
write!(f, " ")?;
b.fmt_sse(f)?;
write!(f, " ")?;
c.fmt_sse(f)?;
write!(f, ")")
}
Self::Coalesce(parameters) => { Self::Coalesce(parameters) => {
write!(f, "(coalesce")?; write!(f, "(coalesce")?;
for p in parameters { for p in parameters {
write!(f, " {:?}", p)?; write!(f, " ")?;
p.fmt_sse(f)?;
} }
write!(f, ")") write!(f, ")")
} }
@ -269,7 +321,7 @@ fn write_arg_list(
} }
/// A function name /// A function name
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum Function { pub enum Function {
Str, Str,
Lang, Lang,
@ -330,8 +382,9 @@ pub enum Function {
Custom(NamedNode), Custom(NamedNode),
} }
impl fmt::Debug for Function { impl Function {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
match self { match self {
Self::Str => write!(f, "str"), Self::Str => write!(f, "str"),
Self::Lang => write!(f, "lang"), Self::Lang => write!(f, "lang"),
@ -389,7 +442,7 @@ impl fmt::Debug for Function {
Self::Object => write!(f, "object"), Self::Object => write!(f, "object"),
#[cfg(feature = "rdf-star")] #[cfg(feature = "rdf-star")]
Self::IsTriple => write!(f, "istriple"), Self::IsTriple => write!(f, "istriple"),
Self::Custom(iri) => iri.fmt(f), Self::Custom(iri) => iri.fmt_sse(f),
} }
} }
} }
@ -459,7 +512,7 @@ impl fmt::Display for Function {
} }
/// A SPARQL query [graph pattern](https://www.w3.org/TR/sparql11-query/#sparqlQuery) /// A SPARQL query [graph pattern](https://www.w3.org/TR/sparql11-query/#sparqlQuery)
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum GraphPattern { pub enum GraphPattern {
/// A [basic graph pattern](https://www.w3.org/TR/sparql11-query/#defn_BasicGraphPattern) /// A [basic graph pattern](https://www.w3.org/TR/sparql11-query/#defn_BasicGraphPattern)
Bgp(Vec<TriplePattern>), Bgp(Vec<TriplePattern>),
@ -535,13 +588,15 @@ pub enum GraphPattern {
}, },
} }
impl fmt::Debug for GraphPattern { impl GraphPattern {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
match self { match self {
Self::Bgp(p) => { Self::Bgp(p) => {
write!(f, "(bgp")?; write!(f, "(bgp")?;
for pattern in p { for pattern in p {
write!(f, " {:?}", pattern)?; write!(f, " ")?;
pattern.fmt_sse(f)?;
} }
write!(f, ")") write!(f, ")")
} }
@ -549,41 +604,91 @@ impl fmt::Debug for GraphPattern {
subject, subject,
path, path,
object, object,
} => write!(f, "(path {:?} {:?} {:?})", subject, path, object), } => {
write!(f, "(path ")?;
subject.fmt_sse(f)?;
write!(f, " ")?;
path.fmt_sse(f)?;
write!(f, " ")?;
object.fmt_sse(f)?;
write!(f, ")")
}
Self::Sequence(elements) => { Self::Sequence(elements) => {
write!(f, "(sequence")?; write!(f, "(sequence")?;
for e in elements { for e in elements {
write!(f, " {:?}", e)?; write!(f, " ")?;
e.fmt_sse(f)?;
} }
write!(f, ")") write!(f, ")")
} }
Self::Join { left, right } => write!(f, "(join {:?} {:?})", left, right), Self::Join { left, right } => {
write!(f, "(join ")?;
left.fmt_sse(f)?;
write!(f, " ")?;
right.fmt_sse(f)?;
write!(f, ")")
}
Self::LeftJoin { left, right, expr } => { Self::LeftJoin { left, right, expr } => {
write!(f, "(leftjoin ")?;
left.fmt_sse(f)?;
write!(f, " ")?;
right.fmt_sse(f)?;
if let Some(expr) = expr { if let Some(expr) = expr {
write!(f, "(leftjoin {:?} {:?} {:?})", left, right, expr) write!(f, " ")?;
} else { expr.fmt_sse(f)?;
write!(f, "(leftjoin {:?} {:?})", left, right)
} }
write!(f, ")")
}
Self::Filter { expr, inner } => {
write!(f, "(filter ")?;
expr.fmt_sse(f)?;
write!(f, " ")?;
inner.fmt_sse(f)?;
write!(f, ")")
}
Self::Union { left, right } => {
write!(f, "(union ")?;
left.fmt_sse(f)?;
write!(f, " ")?;
right.fmt_sse(f)?;
write!(f, ")")
} }
Self::Filter { expr, inner } => write!(f, "(filter {:?} {:?})", expr, inner),
Self::Union { left, right } => write!(f, "(union {:?} {:?})", left, right),
Self::Graph { graph_name, inner } => { Self::Graph { graph_name, inner } => {
write!(f, "(graph {:?} {:?})", graph_name, inner) write!(f, "(graph ")?;
graph_name.fmt_sse(f)?;
write!(f, " ")?;
inner.fmt_sse(f)?;
write!(f, ")")
} }
Self::Extend { inner, var, expr } => { Self::Extend { inner, var, expr } => {
write!(f, "(extend (({:?} {:?})) {:?})", var, expr, inner) write!(f, "(extend ((")?;
var.fmt_sse(f)?;
write!(f, " ")?;
expr.fmt_sse(f)?;
write!(f, ")) ")?;
inner.fmt_sse(f)?;
write!(f, ")")
}
Self::Minus { left, right } => {
write!(f, "(minus ")?;
left.fmt_sse(f)?;
write!(f, " ")?;
right.fmt_sse(f)?;
write!(f, ")")
} }
Self::Minus { left, right } => write!(f, "(minus {:?} {:?})", left, right),
Self::Service { Self::Service {
name, name,
pattern, pattern,
silent, silent,
} => { } => {
write!(f, "(service ")?;
if *silent { if *silent {
write!(f, "(service silent {:?} {:?})", name, pattern) write!(f, "silent ")?;
} else {
write!(f, "(service {:?} {:?})", name, pattern)
} }
name.fmt_sse(f)?;
write!(f, " ")?;
pattern.fmt_sse(f)?;
write!(f, ")")
} }
Self::Group { Self::Group {
inner, inner,
@ -595,28 +700,39 @@ impl fmt::Debug for GraphPattern {
if i > 0 { if i > 0 {
write!(f, " ")?; write!(f, " ")?;
} }
write!(f, "{:?}", v)?; v.fmt_sse(f)?;
} }
write!(f, ") (")?; write!(f, ") (")?;
for (i, (v, a)) in aggregates.iter().enumerate() { for (i, (v, a)) in aggregates.iter().enumerate() {
if i > 0 { if i > 0 {
write!(f, " ")?; write!(f, " ")?;
} }
write!(f, "({:?} {:?})", a, v)?; write!(f, "(")?;
a.fmt_sse(f)?;
write!(f, " ")?;
v.fmt_sse(f)?;
write!(f, ")")?;
} }
write!(f, ") {:?})", inner) write!(f, ") ")?;
inner.fmt_sse(f)?;
write!(f, ")")
} }
Self::Table { variables, rows } => { Self::Table { variables, rows } => {
write!(f, "(table (vars")?; write!(f, "(table (vars")?;
for var in variables { for var in variables {
write!(f, " {:?}", var)?; write!(f, " ")?;
var.fmt_sse(f)?;
} }
write!(f, ")")?; write!(f, ")")?;
for row in rows { for row in rows {
write!(f, " (row")?; write!(f, " (row")?;
for (value, var) in row.iter().zip(variables) { for (value, var) in row.iter().zip(variables) {
if let Some(value) = value { if let Some(value) = value {
write!(f, " ({:?} {:?})", var, value)?; write!(f, " (")?;
var.fmt_sse(f)?;
write!(f, " ")?;
value.fmt_sse(f)?;
write!(f, ")")?;
} }
} }
write!(f, ")")?; write!(f, ")")?;
@ -629,9 +745,11 @@ impl fmt::Debug for GraphPattern {
if i > 0 { if i > 0 {
write!(f, " ")?; write!(f, " ")?;
} }
write!(f, "{:?}", c)?; c.fmt_sse(f)?;
} }
write!(f, ") {:?})", inner) write!(f, ") ")?;
inner.fmt_sse(f)?;
write!(f, ")")
} }
Self::Project { inner, projection } => { Self::Project { inner, projection } => {
write!(f, "(project (")?; write!(f, "(project (")?;
@ -639,22 +757,34 @@ impl fmt::Debug for GraphPattern {
if i > 0 { if i > 0 {
write!(f, " ")?; write!(f, " ")?;
} }
write!(f, "{:?}", v)?; v.fmt_sse(f)?;
} }
write!(f, ") {:?})", inner) write!(f, ") ")?;
inner.fmt_sse(f)?;
write!(f, ")")
}
Self::Distinct { inner } => {
write!(f, "(distinct ")?;
inner.fmt_sse(f)?;
write!(f, ")")
}
Self::Reduced { inner } => {
write!(f, "(reduced ")?;
inner.fmt_sse(f)?;
write!(f, ")")
} }
Self::Distinct { inner } => write!(f, "(distinct {:?})", inner),
Self::Reduced { inner } => write!(f, "(reduced {:?})", inner),
Self::Slice { Self::Slice {
inner, inner,
start, start,
length, length,
} => { } => {
if let Some(length) = length { if let Some(length) = length {
write!(f, "(slice {:?} {:?} {:?})", start, length, inner) write!(f, "(slice {} {} ", start, length)?;
} else { } else {
write!(f, "(slice {:?} _ {:?})", start, inner) write!(f, "(slice {} _ ", start)?;
} }
inner.fmt_sse(f)?;
write!(f, ")")
} }
} }
} }
@ -963,7 +1093,7 @@ impl<'a> fmt::Display for SparqlGraphRootPattern<'a> {
} }
/// A set function used in aggregates (c.f. [`GraphPattern::Group`]) /// A set function used in aggregates (c.f. [`GraphPattern::Group`])
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum AggregationFunction { pub enum AggregationFunction {
/// [Count](https://www.w3.org/TR/sparql11-query/#defn_aggCount) /// [Count](https://www.w3.org/TR/sparql11-query/#defn_aggCount)
Count { Count {
@ -1009,88 +1139,90 @@ pub enum AggregationFunction {
}, },
} }
impl fmt::Debug for AggregationFunction { impl AggregationFunction {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
match self { match self {
Self::Count { expr, distinct } => { Self::Count { expr, distinct } => {
write!(f, "(sum")?;
if *distinct { if *distinct {
if let Some(expr) = expr { write!(f, " distinct")?;
write!(f, "(count distinct {:?})", expr)
} else {
write!(f, "(count distinct)")
}
} else if let Some(expr) = expr {
write!(f, "(count {:?})", expr)
} else {
write!(f, "(count)")
} }
if let Some(expr) = expr {
write!(f, " ")?;
expr.fmt_sse(f)?;
}
write!(f, ")")
} }
Self::Sum { expr, distinct } => { Self::Sum { expr, distinct } => {
write!(f, "(sum ")?;
if *distinct { if *distinct {
write!(f, "(sum distinct {:?})", expr) write!(f, "distinct ")?;
} else {
write!(f, "(sum {:?})", expr)
} }
expr.fmt_sse(f)?;
write!(f, ")")
} }
Self::Avg { expr, distinct } => { Self::Avg { expr, distinct } => {
write!(f, "(avg ")?;
if *distinct { if *distinct {
write!(f, "(avg distinct {:?})", expr) write!(f, "distinct ")?;
} else {
write!(f, "(avg {:?})", expr)
} }
expr.fmt_sse(f)?;
write!(f, ")")
} }
Self::Min { expr, distinct } => { Self::Min { expr, distinct } => {
write!(f, "(min ")?;
if *distinct { if *distinct {
write!(f, "(min distinct {:?})", expr) write!(f, "distinct ")?;
} else {
write!(f, "(min {:?})", expr)
} }
expr.fmt_sse(f)?;
write!(f, ")")
} }
Self::Max { expr, distinct } => { Self::Max { expr, distinct } => {
write!(f, "(max ")?;
if *distinct { if *distinct {
write!(f, "(max distinct {:?})", expr) write!(f, "distinct ")?;
} else {
write!(f, "(max {:?})", expr)
} }
expr.fmt_sse(f)?;
write!(f, ")")
} }
Self::Sample { expr, distinct } => { Self::Sample { expr, distinct } => {
write!(f, "(sample ")?;
if *distinct { if *distinct {
write!(f, "(sample distinct {:?})", expr) write!(f, "distinct ")?;
} else {
write!(f, "(sample {:?})", expr)
} }
expr.fmt_sse(f)?;
write!(f, ")")
} }
Self::GroupConcat { Self::GroupConcat {
expr, expr,
distinct, distinct,
separator, separator,
} => { } => {
write!(f, "(group_concat ")?;
if *distinct { if *distinct {
if let Some(separator) = separator { write!(f, "distinct ")?;
write!(f, "(group_concat distinct {:?} ", expr)?; }
print_quoted_str(separator, f)?; expr.fmt_sse(f)?;
write!(f, ")") if let Some(separator) = separator {
} else { write!(f, " ")?;
write!(f, "(group_concat distinct {:?})", expr)
}
} else if let Some(separator) = separator {
write!(f, "(group_concat {:?} ", expr)?;
print_quoted_str(separator, f)?; print_quoted_str(separator, f)?;
write!(f, ")")
} else {
write!(f, "(group_concat {:?})", expr)
} }
write!(f, ")")
} }
Self::Custom { Self::Custom {
name, name,
expr, expr,
distinct, distinct,
} => { } => {
write!(f, "(")?;
name.fmt_sse(f)?;
if *distinct { if *distinct {
write!(f, "({:?} distinct {:?})", name, expr) write!(f, " distinct")?;
} else {
write!(f, "({:?} {:?})", name, expr)
} }
write!(f, " ")?;
expr.fmt_sse(f)?;
write!(f, ")")
} }
} }
} }
@ -1184,7 +1316,7 @@ impl fmt::Display for AggregationFunction {
} }
/// An ordering comparator used by [`GraphPattern::OrderBy`] /// An ordering comparator used by [`GraphPattern::OrderBy`]
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum OrderComparator { pub enum OrderComparator {
/// Ascending order /// Ascending order
Asc(Expression), Asc(Expression),
@ -1192,11 +1324,20 @@ pub enum OrderComparator {
Desc(Expression), Desc(Expression),
} }
impl fmt::Debug for OrderComparator { impl OrderComparator {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
match self { match self {
Self::Asc(e) => write!(f, "(asc {:?})", e), Self::Asc(e) => {
Self::Desc(e) => write!(f, "(desc {:?})", e), write!(f, "(asc ")?;
e.fmt_sse(f)?;
write!(f, ")")
}
Self::Desc(e) => {
write!(f, "(desc ")?;
e.fmt_sse(f)?;
write!(f, ")")
}
} }
} }
} }
@ -1211,27 +1352,30 @@ impl fmt::Display for OrderComparator {
} }
/// A SPARQL query [dataset specification](https://www.w3.org/TR/sparql11-query/#specifyingDataset) /// A SPARQL query [dataset specification](https://www.w3.org/TR/sparql11-query/#specifyingDataset)
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct QueryDataset { pub struct QueryDataset {
pub default: Vec<NamedNode>, pub default: Vec<NamedNode>,
pub named: Option<Vec<NamedNode>>, pub named: Option<Vec<NamedNode>>,
} }
impl fmt::Debug for QueryDataset { impl QueryDataset {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
write!(f, "(")?; write!(f, "(")?;
for (i, graph_name) in self.default.iter().enumerate() { for (i, graph_name) in self.default.iter().enumerate() {
if i > 0 { if i > 0 {
write!(f, " ")?; write!(f, " ")?;
} }
write!(f, "{:?}", graph_name)?; graph_name.fmt_sse(f)?;
} }
if let Some(named) = &self.named { if let Some(named) = &self.named {
for (i, graph_name) in named.iter().enumerate() { for (i, graph_name) in named.iter().enumerate() {
if !self.default.is_empty() || i > 0 { if !self.default.is_empty() || i > 0 {
write!(f, " ")?; write!(f, " ")?;
} }
write!(f, "(named {:?})", graph_name)?; write!(f, "(named ")?;
graph_name.fmt_sse(f)?;
write!(f, ")")?;
} }
} }
write!(f, ")") write!(f, ")")
@ -1255,7 +1399,7 @@ impl fmt::Display for QueryDataset {
/// A target RDF graph for update operations /// A target RDF graph for update operations
/// ///
/// Could be a specific graph, all named graphs or the complete dataset. /// Could be a specific graph, all named graphs or the complete dataset.
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum GraphTarget { pub enum GraphTarget {
NamedNode(NamedNode), NamedNode(NamedNode),
DefaultGraph, DefaultGraph,
@ -1263,10 +1407,11 @@ pub enum GraphTarget {
AllGraphs, AllGraphs,
} }
impl fmt::Debug for GraphTarget { impl GraphTarget {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
match self { match self {
Self::NamedNode(node) => node.fmt(f), Self::NamedNode(node) => node.fmt_sse(f),
Self::DefaultGraph => write!(f, "default"), Self::DefaultGraph => write!(f, "default"),
Self::NamedGraphs => write!(f, "named"), Self::NamedGraphs => write!(f, "named"),
Self::AllGraphs => write!(f, "all"), Self::AllGraphs => write!(f, "all"),
@ -1299,3 +1444,24 @@ impl From<GraphName> for GraphTarget {
} }
} }
} }
#[inline]
fn fmt_sse_unary_expression(f: &mut impl fmt::Write, name: &str, e: &Expression) -> fmt::Result {
write!(f, "({} ", name)?;
e.fmt_sse(f)?;
write!(f, ")")
}
#[inline]
fn fmt_sse_binary_expression(
f: &mut impl fmt::Write,
name: &str,
a: &Expression,
b: &Expression,
) -> fmt::Result {
write!(f, "({} ", name)?;
a.fmt_sse(f)?;
write!(f, " ")?;
b.fmt_sse(f)?;
write!(f, ")")
}

@ -344,7 +344,7 @@ impl<F, T: From<F>> From<FocusedTriplePattern<F>> for FocusedTripleOrPathPattern
} }
} }
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
enum PartialGraphPattern { enum PartialGraphPattern {
Optional(GraphPattern, Option<Expression>), Optional(GraphPattern, Option<Expression>),
Minus(GraphPattern), Minus(GraphPattern),

@ -8,19 +8,16 @@ use std::str::FromStr;
/// A parsed [SPARQL query](https://www.w3.org/TR/sparql11-query/) /// A parsed [SPARQL query](https://www.w3.org/TR/sparql11-query/)
/// ///
/// The `Display` trait prints a serialization of the query using SPARQL syntax and
/// `Debug` prints the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
///
/// ``` /// ```
/// use spargebra::Query; /// use spargebra::Query;
/// ///
/// let query_str = "SELECT ?s ?p ?o WHERE { ?s ?p ?o . }"; /// let query_str = "SELECT ?s ?p ?o WHERE { ?s ?p ?o . }";
/// let query = Query::parse(query_str, None)?; /// let query = Query::parse(query_str, None)?;
/// assert_eq!(query.to_string(), query_str); /// assert_eq!(query.to_string(), query_str);
/// assert_eq!(format!("{:?}", query), "(project (?s ?p ?o) (bgp (triple ?s ?p ?o)))"); /// assert_eq!(query.to_sse(), "(project (?s ?p ?o) (bgp (triple ?s ?p ?o)))");
/// # Result::Ok::<_, spargebra::ParseError>(()) /// # Result::Ok::<_, spargebra::ParseError>(())
/// ``` /// ```
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum Query { pub enum Query {
/// [SELECT](https://www.w3.org/TR/sparql11-query/#select) /// [SELECT](https://www.w3.org/TR/sparql11-query/#select)
Select { Select {
@ -67,10 +64,17 @@ impl Query {
pub fn parse(query: &str, base_iri: Option<&str>) -> Result<Self, ParseError> { pub fn parse(query: &str, base_iri: Option<&str>) -> Result<Self, ParseError> {
parse_query(query, base_iri) parse_query(query, base_iri)
} }
}
impl fmt::Debug for Query { /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub fn to_sse(&self) -> String {
let mut buffer = String::new();
self.fmt_sse(&mut buffer)
.expect("Unexpected error during SSE formatting");
buffer
}
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
match self { match self {
Query::Select { Query::Select {
dataset, dataset,
@ -81,9 +85,11 @@ impl fmt::Debug for Query {
write!(f, "(base <{}> ", base_iri)?; write!(f, "(base <{}> ", base_iri)?;
} }
if let Some(dataset) = dataset { if let Some(dataset) = dataset {
write!(f, "(dataset {:?} ", dataset)?; write!(f, "(dataset ")?;
dataset.fmt_sse(f)?;
write!(f, " ")?;
} }
write!(f, "{:?}", pattern)?; pattern.fmt_sse(f)?;
if dataset.is_some() { if dataset.is_some() {
write!(f, ")")?; write!(f, ")")?;
} }
@ -106,13 +112,15 @@ impl fmt::Debug for Query {
if i > 0 { if i > 0 {
write!(f, " ")?; write!(f, " ")?;
} }
write!(f, "{:?}", t)?; t.fmt_sse(f)?;
} }
write!(f, ") ")?; write!(f, ") ")?;
if let Some(dataset) = dataset { if let Some(dataset) = dataset {
write!(f, "(dataset {:?} ", dataset)?; write!(f, "(dataset ")?;
dataset.fmt_sse(f)?;
write!(f, " ")?;
} }
write!(f, "{:?}", pattern)?; pattern.fmt_sse(f)?;
if dataset.is_some() { if dataset.is_some() {
write!(f, ")")?; write!(f, ")")?;
} }
@ -132,9 +140,11 @@ impl fmt::Debug for Query {
} }
write!(f, "(describe ")?; write!(f, "(describe ")?;
if let Some(dataset) = dataset { if let Some(dataset) = dataset {
write!(f, "(dataset {:?} ", dataset)?; write!(f, "(dataset ")?;
dataset.fmt_sse(f)?;
write!(f, " ")?;
} }
write!(f, "{:?}", pattern)?; pattern.fmt_sse(f)?;
if dataset.is_some() { if dataset.is_some() {
write!(f, ")")?; write!(f, ")")?;
} }
@ -154,9 +164,11 @@ impl fmt::Debug for Query {
} }
write!(f, "(ask ")?; write!(f, "(ask ")?;
if let Some(dataset) = dataset { if let Some(dataset) = dataset {
write!(f, "(dataset {:?} ", dataset)?; write!(f, "(dataset ")?;
dataset.fmt_sse(f)?;
write!(f, " ")?;
} }
write!(f, "{:?}", pattern)?; pattern.fmt_sse(f)?;
if dataset.is_some() { if dataset.is_some() {
write!(f, ")")?; write!(f, ")")?;
} }

@ -16,15 +16,15 @@ use std::fmt::Write;
/// NamedNode { iri: "http://example.com/foo".into() }.to_string() /// NamedNode { iri: "http://example.com/foo".into() }.to_string()
/// ) /// )
/// ``` /// ```
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Hash)] #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub struct NamedNode { pub struct NamedNode {
/// The [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) itself. /// The [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) itself.
pub iri: String, pub iri: String,
} }
impl fmt::Debug for NamedNode { impl NamedNode {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
write!(f, "<{}>", self.iri) write!(f, "<{}>", self.iri)
} }
} }
@ -61,15 +61,15 @@ impl TryFrom<NamedNodePattern> for NamedNode {
/// BlankNode { id: "a1".into() }.to_string() /// BlankNode { id: "a1".into() }.to_string()
/// ) /// )
/// ``` /// ```
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct BlankNode { pub struct BlankNode {
/// The [blank node identifier](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node-identifier). /// The [blank node identifier](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node-identifier).
pub id: String, pub id: String,
} }
impl fmt::Debug for BlankNode { impl BlankNode {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
write!(f, "_:{}", self.id) write!(f, "_:{}", self.id)
} }
} }
@ -106,7 +106,7 @@ impl fmt::Display for BlankNode {
/// Literal::LanguageTaggedString { value: "foo".into(), language: "en".into() }.to_string() /// Literal::LanguageTaggedString { value: "foo".into(), language: "en".into() }.to_string()
/// ); /// );
/// ``` /// ```
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum Literal { pub enum Literal {
/// A [simple literal](https://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal) without datatype or language form. /// A [simple literal](https://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal) without datatype or language form.
Simple { Simple {
@ -129,9 +129,9 @@ pub enum Literal {
}, },
} }
impl fmt::Debug for Literal { impl Literal {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self { match self {
Literal::Simple { value } => print_quoted_str(value, f), Literal::Simple { value } => print_quoted_str(value, f),
Literal::LanguageTaggedString { value, language } => { Literal::LanguageTaggedString { value, language } => {
@ -166,7 +166,7 @@ impl fmt::Display for Literal {
/// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [blank nodes](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node). /// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [blank nodes](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node).
/// ///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation. /// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation.
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum Subject { pub enum Subject {
NamedNode(NamedNode), NamedNode(NamedNode),
BlankNode(BlankNode), BlankNode(BlankNode),
@ -174,14 +174,14 @@ pub enum Subject {
Triple(Box<Triple>), Triple(Box<Triple>),
} }
impl fmt::Debug for Subject { impl Subject {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self { match self {
Self::NamedNode(node) => node.fmt(f), Self::NamedNode(node) => node.fmt_sse(f),
Self::BlankNode(node) => node.fmt(f), Self::BlankNode(node) => node.fmt_sse(f),
#[cfg(feature = "rdf-star")] #[cfg(feature = "rdf-star")]
Self::Triple(triple) => triple.fmt(f), Self::Triple(triple) => triple.fmt_sse(f),
} }
} }
} }
@ -242,20 +242,20 @@ impl TryFrom<TermPattern> for Subject {
/// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [triples](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple). /// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [triples](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple).
/// ///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation. /// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation.
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum GroundSubject { pub enum GroundSubject {
NamedNode(NamedNode), NamedNode(NamedNode),
#[cfg(feature = "rdf-star")] #[cfg(feature = "rdf-star")]
Triple(Box<GroundTriple>), Triple(Box<GroundTriple>),
} }
impl fmt::Debug for GroundSubject { impl GroundSubject {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self { match self {
Self::NamedNode(node) => node.fmt(f), Self::NamedNode(node) => node.fmt_sse(f),
#[cfg(feature = "rdf-star")] #[cfg(feature = "rdf-star")]
Self::Triple(triple) => triple.fmt(f), Self::Triple(triple) => triple.fmt_sse(f),
} }
} }
} }
@ -323,7 +323,7 @@ impl TryFrom<GroundTerm> for GroundSubject {
/// It is the union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri), [blank nodes](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node) and [literals](https://www.w3.org/TR/rdf11-concepts/#dfn-literal). /// It is the union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri), [blank nodes](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node) and [literals](https://www.w3.org/TR/rdf11-concepts/#dfn-literal).
/// ///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation. /// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation.
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum Term { pub enum Term {
NamedNode(NamedNode), NamedNode(NamedNode),
BlankNode(BlankNode), BlankNode(BlankNode),
@ -332,15 +332,15 @@ pub enum Term {
Triple(Box<Triple>), Triple(Box<Triple>),
} }
impl fmt::Debug for Term { impl Term {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self { match self {
Self::NamedNode(node) => node.fmt(f), Self::NamedNode(node) => node.fmt_sse(f),
Self::BlankNode(node) => node.fmt(f), Self::BlankNode(node) => node.fmt_sse(f),
Self::Literal(literal) => literal.fmt(f), Self::Literal(literal) => literal.fmt_sse(f),
#[cfg(feature = "rdf-star")] #[cfg(feature = "rdf-star")]
Self::Triple(triple) => triple.fmt(f), Self::Triple(triple) => triple.fmt_sse(f),
} }
} }
} }
@ -422,7 +422,7 @@ impl TryFrom<TermPattern> for Term {
/// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri), [literals](https://www.w3.org/TR/rdf11-concepts/#dfn-literal) and [triples](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple). /// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri), [literals](https://www.w3.org/TR/rdf11-concepts/#dfn-literal) and [triples](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple).
/// ///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation. /// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation.
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum GroundTerm { pub enum GroundTerm {
NamedNode(NamedNode), NamedNode(NamedNode),
Literal(Literal), Literal(Literal),
@ -430,14 +430,14 @@ pub enum GroundTerm {
Triple(Box<GroundTriple>), Triple(Box<GroundTriple>),
} }
impl fmt::Debug for GroundTerm { impl GroundTerm {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self { match self {
Self::NamedNode(node) => node.fmt(f), Self::NamedNode(node) => node.fmt_sse(f),
Self::Literal(literal) => literal.fmt(f), Self::Literal(literal) => literal.fmt_sse(f),
#[cfg(feature = "rdf-star")] #[cfg(feature = "rdf-star")]
Self::Triple(triple) => triple.fmt(f), Self::Triple(triple) => triple.fmt_sse(f),
} }
} }
} }
@ -512,21 +512,23 @@ impl TryFrom<Term> for GroundTerm {
/// }.to_string() /// }.to_string()
/// ) /// )
/// ``` /// ```
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct Triple { pub struct Triple {
pub subject: Subject, pub subject: Subject,
pub predicate: NamedNode, pub predicate: NamedNode,
pub object: Term, pub object: Term,
} }
impl fmt::Debug for Triple { impl Triple {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
write!( write!(f, "(triple ")?;
f, self.subject.fmt_sse(f)?;
"(triple {:?} {:?} {:?})", write!(f, " ")?;
self.subject, self.predicate, self.object self.predicate.fmt_sse(f)?;
) write!(f, " ")?;
self.object.fmt_sse(f)?;
write!(f, ")")
} }
} }
@ -567,21 +569,23 @@ impl TryFrom<TriplePattern> for Triple {
/// }.to_string() /// }.to_string()
/// ) /// )
/// ``` /// ```
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct GroundTriple { pub struct GroundTriple {
pub subject: GroundSubject, pub subject: GroundSubject,
pub predicate: NamedNode, pub predicate: NamedNode,
pub object: GroundTerm, pub object: GroundTerm,
} }
impl fmt::Debug for GroundTriple { impl GroundTriple {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
write!( write!(f, "(triple ")?;
f, self.subject.fmt_sse(f)?;
"(triple {:?} {:?} {:?})", write!(f, " ")?;
self.subject, self.predicate, self.object self.predicate.fmt_sse(f)?;
) write!(f, " ")?;
self.object.fmt_sse(f)?;
write!(f, ")")
} }
} }
@ -608,17 +612,17 @@ impl TryFrom<Triple> for GroundTriple {
/// A possible graph name. /// A possible graph name.
/// ///
/// It is the union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and the [default graph name](https://www.w3.org/TR/rdf11-concepts/#dfn-default-graph). /// It is the union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and the [default graph name](https://www.w3.org/TR/rdf11-concepts/#dfn-default-graph).
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum GraphName { pub enum GraphName {
NamedNode(NamedNode), NamedNode(NamedNode),
DefaultGraph, DefaultGraph,
} }
impl fmt::Debug for GraphName { impl GraphName {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self { match self {
Self::NamedNode(node) => node.fmt(f), Self::NamedNode(node) => node.fmt_sse(f),
Self::DefaultGraph => write!(f, "default"), Self::DefaultGraph => write!(f, "default"),
} }
} }
@ -672,7 +676,7 @@ impl TryFrom<GraphNamePattern> for GraphName {
/// }.to_string() /// }.to_string()
/// ) /// )
/// ``` /// ```
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct Quad { pub struct Quad {
pub subject: Subject, pub subject: Subject,
pub predicate: NamedNode, pub predicate: NamedNode,
@ -680,22 +684,25 @@ pub struct Quad {
pub graph_name: GraphName, pub graph_name: GraphName,
} }
impl fmt::Debug for Quad { impl Quad {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
if self.graph_name == GraphName::DefaultGraph { if self.graph_name != GraphName::DefaultGraph {
write!( write!(f, "(graph ")?;
f, self.graph_name.fmt_sse(f)?;
"(triple {:?} {:?} {:?})", write!(f, " (")?;
self.subject, self.predicate, self.object
)
} else {
write!(
f,
"(graph {:?} ((triple {:?} {:?} {:?})))",
self.graph_name, self.subject, self.predicate, self.object
)
} }
write!(f, "(triple ")?;
self.subject.fmt_sse(f)?;
write!(f, " ")?;
self.predicate.fmt_sse(f)?;
write!(f, " ")?;
self.object.fmt_sse(f)?;
write!(f, ")")?;
if self.graph_name != GraphName::DefaultGraph {
write!(f, "))")?;
}
Ok(())
} }
} }
@ -746,7 +753,7 @@ impl TryFrom<QuadPattern> for Quad {
/// }.to_string() /// }.to_string()
/// ) /// )
/// ``` /// ```
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct GroundQuad { pub struct GroundQuad {
pub subject: GroundSubject, pub subject: GroundSubject,
pub predicate: NamedNode, pub predicate: NamedNode,
@ -754,22 +761,25 @@ pub struct GroundQuad {
pub graph_name: GraphName, pub graph_name: GraphName,
} }
impl fmt::Debug for GroundQuad { impl GroundQuad {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
if self.graph_name == GraphName::DefaultGraph { if self.graph_name != GraphName::DefaultGraph {
write!( write!(f, "(graph ")?;
f, self.graph_name.fmt_sse(f)?;
"(triple {:?} {:?} {:?})", write!(f, " (")?;
self.subject, self.predicate, self.object }
) write!(f, "(triple ")?;
} else { self.subject.fmt_sse(f)?;
write!( write!(f, " ")?;
f, self.predicate.fmt_sse(f)?;
"(graph {:?} ((triple {:?} {:?} {:?})))", write!(f, " ")?;
self.graph_name, self.subject, self.predicate, self.object self.object.fmt_sse(f)?;
) write!(f, ")")?;
if self.graph_name != GraphName::DefaultGraph {
write!(f, "))")?;
} }
Ok(())
} }
} }
@ -812,14 +822,14 @@ impl TryFrom<Quad> for GroundQuad {
/// Variable { name: "foo".into() }.to_string() /// Variable { name: "foo".into() }.to_string()
/// ); /// );
/// ``` /// ```
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Hash)] #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub struct Variable { pub struct Variable {
pub name: String, pub name: String,
} }
impl fmt::Debug for Variable { impl Variable {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
write!(f, "?{}", self.name) write!(f, "?{}", self.name)
} }
} }
@ -832,18 +842,18 @@ impl fmt::Display for Variable {
} }
/// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [variables](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables). /// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [variables](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables).
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum NamedNodePattern { pub enum NamedNodePattern {
NamedNode(NamedNode), NamedNode(NamedNode),
Variable(Variable), Variable(Variable),
} }
impl fmt::Debug for NamedNodePattern { impl NamedNodePattern {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self { match self {
Self::NamedNode(node) => node.fmt(f), Self::NamedNode(node) => node.fmt_sse(f),
Self::Variable(var) => var.fmt(f), Self::Variable(var) => var.fmt_sse(f),
} }
} }
} }
@ -873,7 +883,7 @@ impl From<Variable> for NamedNodePattern {
} }
/// The union of [terms](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-term) and [variables](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables). /// The union of [terms](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-term) and [variables](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables).
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum TermPattern { pub enum TermPattern {
NamedNode(NamedNode), NamedNode(NamedNode),
BlankNode(BlankNode), BlankNode(BlankNode),
@ -883,16 +893,16 @@ pub enum TermPattern {
Variable(Variable), Variable(Variable),
} }
impl fmt::Debug for TermPattern { impl TermPattern {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self { match self {
Self::NamedNode(term) => term.fmt(f), Self::NamedNode(term) => term.fmt_sse(f),
Self::BlankNode(term) => term.fmt(f), Self::BlankNode(term) => term.fmt_sse(f),
Self::Literal(term) => term.fmt(f), Self::Literal(term) => term.fmt_sse(f),
#[cfg(feature = "rdf-star")] #[cfg(feature = "rdf-star")]
Self::Triple(triple) => triple.fmt(f), Self::Triple(triple) => triple.fmt_sse(f),
Self::Variable(var) => var.fmt(f), Self::Variable(var) => var.fmt_sse(f),
} }
} }
} }
@ -982,7 +992,7 @@ impl From<NamedNodePattern> for TermPattern {
} }
/// The union of [terms](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-term) and [variables](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables) without blank nodes. /// The union of [terms](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-term) and [variables](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables) without blank nodes.
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum GroundTermPattern { pub enum GroundTermPattern {
NamedNode(NamedNode), NamedNode(NamedNode),
Literal(Literal), Literal(Literal),
@ -990,14 +1000,14 @@ pub enum GroundTermPattern {
Triple(Box<GroundTriplePattern>), Triple(Box<GroundTriplePattern>),
} }
impl fmt::Debug for GroundTermPattern { impl GroundTermPattern {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self { match self {
Self::NamedNode(term) => term.fmt(f), Self::NamedNode(term) => term.fmt_sse(f),
Self::Literal(term) => term.fmt(f), Self::Literal(term) => term.fmt_sse(f),
Self::Variable(var) => var.fmt(f), Self::Variable(var) => var.fmt_sse(f),
Self::Triple(triple) => write!(f, "<<{}>>", triple), Self::Triple(triple) => triple.fmt_sse(f),
} }
} }
} }
@ -1091,20 +1101,20 @@ impl TryFrom<TermPattern> for GroundTermPattern {
} }
/// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri), [default graph name](https://www.w3.org/TR/rdf11-concepts/#dfn-default-graph) and [variables](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables). /// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri), [default graph name](https://www.w3.org/TR/rdf11-concepts/#dfn-default-graph) and [variables](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables).
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum GraphNamePattern { pub enum GraphNamePattern {
NamedNode(NamedNode), NamedNode(NamedNode),
DefaultGraph, DefaultGraph,
Variable(Variable), Variable(Variable),
} }
impl fmt::Debug for GraphNamePattern { impl GraphNamePattern {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self { match self {
Self::NamedNode(node) => node.fmt(f), Self::NamedNode(node) => node.fmt_sse(f),
Self::DefaultGraph => write!(f, "default"), Self::DefaultGraph => write!(f, "default"),
Self::Variable(var) => var.fmt(f), Self::Variable(var) => var.fmt_sse(f),
} }
} }
} }
@ -1155,7 +1165,7 @@ impl From<NamedNodePattern> for GraphNamePattern {
} }
/// A [triple pattern](https://www.w3.org/TR/sparql11-query/#defn_TriplePattern) /// A [triple pattern](https://www.w3.org/TR/sparql11-query/#defn_TriplePattern)
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct TriplePattern { pub struct TriplePattern {
pub subject: TermPattern, pub subject: TermPattern,
pub predicate: NamedNodePattern, pub predicate: NamedNodePattern,
@ -1176,14 +1186,16 @@ impl TriplePattern {
} }
} }
impl fmt::Debug for TriplePattern { impl TriplePattern {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
write!( write!(f, "(triple ")?;
f, self.subject.fmt_sse(f)?;
"(triple {:?} {:?} {:?})", write!(f, " ")?;
self.subject, self.predicate, self.object self.predicate.fmt_sse(f)?;
) write!(f, " ")?;
self.object.fmt_sse(f)?;
write!(f, ")")
} }
} }
@ -1206,21 +1218,23 @@ impl From<Triple> for TriplePattern {
} }
/// A [triple pattern](https://www.w3.org/TR/sparql11-query/#defn_TriplePattern) without blank nodes /// A [triple pattern](https://www.w3.org/TR/sparql11-query/#defn_TriplePattern) without blank nodes
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct GroundTriplePattern { pub struct GroundTriplePattern {
pub subject: GroundTermPattern, pub subject: GroundTermPattern,
pub predicate: NamedNodePattern, pub predicate: NamedNodePattern,
pub object: GroundTermPattern, pub object: GroundTermPattern,
} }
impl fmt::Debug for GroundTriplePattern { impl GroundTriplePattern {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
write!( write!(f, "(triple ")?;
f, self.subject.fmt_sse(f)?;
"(triple {:?} {:?} {:?})", write!(f, " ")?;
self.subject, self.predicate, self.object self.predicate.fmt_sse(f)?;
) write!(f, " ")?;
self.object.fmt_sse(f)?;
write!(f, ")")
} }
} }
@ -1256,7 +1270,7 @@ impl TryFrom<TriplePattern> for GroundTriplePattern {
} }
/// A [triple pattern](https://www.w3.org/TR/sparql11-query/#defn_TriplePattern) in a specific graph /// A [triple pattern](https://www.w3.org/TR/sparql11-query/#defn_TriplePattern) in a specific graph
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct QuadPattern { pub struct QuadPattern {
pub subject: TermPattern, pub subject: TermPattern,
pub predicate: NamedNodePattern, pub predicate: NamedNodePattern,
@ -1280,22 +1294,25 @@ impl QuadPattern {
} }
} }
impl fmt::Debug for QuadPattern { impl QuadPattern {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
if self.graph_name == GraphNamePattern::DefaultGraph { if self.graph_name != GraphNamePattern::DefaultGraph {
write!( write!(f, "(graph ")?;
f, self.graph_name.fmt_sse(f)?;
"(triple {:?} {:?} {:?})", write!(f, " (")?;
self.subject, self.predicate, self.object
)
} else {
write!(
f,
"(graph {:?} ((triple {:?} {:?} {:?})))",
self.graph_name, self.subject, self.predicate, self.object
)
} }
write!(f, "(triple ")?;
self.subject.fmt_sse(f)?;
write!(f, " ")?;
self.predicate.fmt_sse(f)?;
write!(f, " ")?;
self.object.fmt_sse(f)?;
write!(f, ")")?;
if self.graph_name != GraphNamePattern::DefaultGraph {
write!(f, "))")?;
}
Ok(())
} }
} }
@ -1315,7 +1332,7 @@ impl fmt::Display for QuadPattern {
} }
/// A [triple pattern](https://www.w3.org/TR/sparql11-query/#defn_TriplePattern) in a specific graph without blank nodes /// A [triple pattern](https://www.w3.org/TR/sparql11-query/#defn_TriplePattern) in a specific graph without blank nodes
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct GroundQuadPattern { pub struct GroundQuadPattern {
pub subject: GroundTermPattern, pub subject: GroundTermPattern,
pub predicate: NamedNodePattern, pub predicate: NamedNodePattern,
@ -1323,22 +1340,25 @@ pub struct GroundQuadPattern {
pub graph_name: GraphNamePattern, pub graph_name: GraphNamePattern,
} }
impl fmt::Debug for GroundQuadPattern { impl GroundQuadPattern {
#[inline] /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
if self.graph_name == GraphNamePattern::DefaultGraph { if self.graph_name != GraphNamePattern::DefaultGraph {
write!( write!(f, "(graph ")?;
f, self.graph_name.fmt_sse(f)?;
"(triple {:?} {:?} {:?})", write!(f, " (")?;
self.subject, self.predicate, self.object }
) write!(f, "(triple ")?;
} else { self.subject.fmt_sse(f)?;
write!( write!(f, " ")?;
f, self.predicate.fmt_sse(f)?;
"(graph {:?} ((triple {:?} {:?} {:?})))", write!(f, " ")?;
self.graph_name, self.subject, self.predicate, self.object self.object.fmt_sse(f)?;
) write!(f, ")")?;
if self.graph_name != GraphNamePattern::DefaultGraph {
write!(f, "))")?;
} }
Ok(())
} }
} }
@ -1372,7 +1392,7 @@ impl TryFrom<QuadPattern> for GroundQuadPattern {
} }
#[inline] #[inline]
pub(crate) fn print_quoted_str(string: &str, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub(crate) fn print_quoted_str(string: &str, f: &mut impl Write) -> fmt::Result {
f.write_char('"')?; f.write_char('"')?;
for c in string.chars() { for c in string.chars() {
match c { match c {

@ -8,19 +8,16 @@ use std::str::FromStr;
/// A parsed [SPARQL update](https://www.w3.org/TR/sparql11-update/) /// A parsed [SPARQL update](https://www.w3.org/TR/sparql11-update/)
/// ///
/// The `Display` trait prints a serialization of the update using SPARQL syntax and
/// `Debug` prints the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
///
/// ``` /// ```
/// use spargebra::Update; /// use spargebra::Update;
/// ///
/// let update_str = "CLEAR ALL ;"; /// let update_str = "CLEAR ALL ;";
/// let update = Update::parse(update_str, None)?; /// let update = Update::parse(update_str, None)?;
/// assert_eq!(update.to_string().trim(), update_str); /// assert_eq!(update.to_string().trim(), update_str);
/// assert_eq!(format!("{:?}", update), "(update (clear all))"); /// assert_eq!(update.to_sse(), "(update (clear all))");
/// # Result::Ok::<_, spargebra::ParseError>(()) /// # Result::Ok::<_, spargebra::ParseError>(())
/// ``` /// ```
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct Update { pub struct Update {
/// The update base IRI /// The update base IRI
pub base_iri: Option<Iri<String>>, pub base_iri: Option<Iri<String>>,
@ -33,16 +30,24 @@ impl Update {
pub fn parse(update: &str, base_iri: Option<&str>) -> Result<Self, ParseError> { pub fn parse(update: &str, base_iri: Option<&str>) -> Result<Self, ParseError> {
parse_update(update, base_iri) parse_update(update, base_iri)
} }
}
impl fmt::Debug for Update { /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub fn to_sse(&self) -> String {
let mut buffer = String::new();
self.fmt_sse(&mut buffer)
.expect("Unexpected error during SSE formatting");
buffer
}
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
if let Some(base_iri) = &self.base_iri { if let Some(base_iri) = &self.base_iri {
write!(f, "(base <{}> ", base_iri)?; write!(f, "(base <{}> ", base_iri)?;
} }
write!(f, "(update")?; write!(f, "(update")?;
for op in &self.operations { for op in &self.operations {
write!(f, " {:?}", op)?; write!(f, " ")?;
op.fmt_sse(f)?;
} }
write!(f, ")")?; write!(f, ")")?;
if self.base_iri.is_some() { if self.base_iri.is_some() {
@ -89,7 +94,7 @@ impl<'a> TryFrom<&'a String> for Update {
} }
/// The [graph update operations](https://www.w3.org/TR/sparql11-update/#formalModelGraphUpdate) /// The [graph update operations](https://www.w3.org/TR/sparql11-update/#formalModelGraphUpdate)
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum GraphUpdateOperation { pub enum GraphUpdateOperation {
/// [insert data](https://www.w3.org/TR/sparql11-update/#defn_insertDataOperation) /// [insert data](https://www.w3.org/TR/sparql11-update/#defn_insertDataOperation)
InsertData { data: Vec<Quad> }, InsertData { data: Vec<Quad> },
@ -116,8 +121,9 @@ pub enum GraphUpdateOperation {
Drop { silent: bool, graph: GraphTarget }, Drop { silent: bool, graph: GraphTarget },
} }
impl fmt::Debug for GraphUpdateOperation { impl GraphUpdateOperation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
match self { match self {
GraphUpdateOperation::InsertData { data } => { GraphUpdateOperation::InsertData { data } => {
write!(f, "(insertData (")?; write!(f, "(insertData (")?;
@ -125,7 +131,7 @@ impl fmt::Debug for GraphUpdateOperation {
if i > 0 { if i > 0 {
write!(f, " ")?; write!(f, " ")?;
} }
write!(f, "{:?}", t)?; t.fmt_sse(f)?;
} }
write!(f, "))") write!(f, "))")
} }
@ -135,7 +141,7 @@ impl fmt::Debug for GraphUpdateOperation {
if i > 0 { if i > 0 {
write!(f, " ")?; write!(f, " ")?;
} }
write!(f, "{:?}", t)?; t.fmt_sse(f)?;
} }
write!(f, "))") write!(f, "))")
} }
@ -145,13 +151,15 @@ impl fmt::Debug for GraphUpdateOperation {
using, using,
pattern, pattern,
} => { } => {
write!(f, "(modify")?; write!(f, "(modify ")?;
if let Some(using) = using { if let Some(using) = using {
write!(f, " (using {:?}", using)?; write!(f, " (using ")?;
} using.fmt_sse(f)?;
write!(f, " {:?}", pattern)?; write!(f, " ")?;
if using.is_some() { pattern.fmt_sse(f)?;
write!(f, ")")?; write!(f, ")")?;
} else {
pattern.fmt_sse(f)?;
} }
if !delete.is_empty() { if !delete.is_empty() {
write!(f, " (delete (")?; write!(f, " (delete (")?;
@ -159,7 +167,7 @@ impl fmt::Debug for GraphUpdateOperation {
if i > 0 { if i > 0 {
write!(f, " ")?; write!(f, " ")?;
} }
write!(f, "{:?}", t)?; t.fmt_sse(f)?;
} }
write!(f, "))")?; write!(f, "))")?;
} }
@ -169,39 +177,45 @@ impl fmt::Debug for GraphUpdateOperation {
if i > 0 { if i > 0 {
write!(f, " ")?; write!(f, " ")?;
} }
write!(f, "{:?}", t)?; t.fmt_sse(f)?;
} }
write!(f, "))")?; write!(f, "))")?;
} }
write!(f, ")") write!(f, ")")
} }
GraphUpdateOperation::Load { silent, from, to } => { GraphUpdateOperation::Load { silent, from, to } => {
write!(f, "(load")?; write!(f, "(load ")?;
if *silent { if *silent {
write!(f, " silent")?; write!(f, "silent ")?;
} }
write!(f, " {:?} {:?}", from, to) from.fmt_sse(f)?;
write!(f, " ")?;
to.fmt_sse(f)?;
write!(f, ")")
} }
GraphUpdateOperation::Clear { silent, graph } => { GraphUpdateOperation::Clear { silent, graph } => {
write!(f, "(clear")?; write!(f, "(clear ")?;
if *silent { if *silent {
write!(f, " silent")?; write!(f, "silent ")?;
} }
write!(f, " {:?})", graph) graph.fmt_sse(f)?;
write!(f, ")")
} }
GraphUpdateOperation::Create { silent, graph } => { GraphUpdateOperation::Create { silent, graph } => {
write!(f, "(create")?; write!(f, "(create ")?;
if *silent { if *silent {
write!(f, " silent")?; write!(f, "silent ")?;
} }
write!(f, " {:?})", graph) graph.fmt_sse(f)?;
write!(f, ")")
} }
GraphUpdateOperation::Drop { silent, graph } => { GraphUpdateOperation::Drop { silent, graph } => {
write!(f, "(drop")?; write!(f, "(drop ")?;
if *silent { if *silent {
write!(f, " silent")?; write!(f, "silent ")?;
} }
write!(f, " {:?})", graph) graph.fmt_sse(f)?;
write!(f, ")")
} }
} }
} }

Loading…
Cancel
Save