Makes SPARQL-star optional in the SPARQL parser

pull/171/head
Tpt 3 years ago
parent 2067be1a0e
commit 25e192095e
  1. 2
      lib/Cargo.toml
  2. 7
      spargebra/Cargo.toml
  3. 4
      spargebra/README.md
  4. 26
      spargebra/src/algebra.rs
  5. 2
      spargebra/src/lib.rs
  6. 87
      spargebra/src/parser.rs
  7. 26
      spargebra/src/term.rs

@ -44,7 +44,7 @@ http = "0.2"
httparse = { version = "1", optional = true } httparse = { version = "1", optional = true }
native-tls = { version = "0.2", optional = true } native-tls = { version = "0.2", optional = true }
json-event-parser = "0.1" json-event-parser = "0.1"
spargebra = { version = "0.1", path="../spargebra" } spargebra = { version = "0.1", path="../spargebra", features = ["rdf-star"] }
[dev-dependencies] [dev-dependencies]

@ -12,8 +12,15 @@ A SPARQL parser
""" """
edition = "2018" edition = "2018"
[features]
default = []
rdf-star = []
[dependencies] [dependencies]
peg = "0.7" peg = "0.7"
rand = "0.8" rand = "0.8"
oxiri = "0.1" oxiri = "0.1"
oxilangtag = "0.1" oxilangtag = "0.1"
[package.metadata.docs.rs]
all-features = true

@ -9,7 +9,9 @@ Spargebra
Spargebra is a [SPARQL](https://www.w3.org/TR/sparql11-overview/) parser. Spargebra is a [SPARQL](https://www.w3.org/TR/sparql11-overview/) parser.
It supports [SPARQL 1.1 Query](https://www.w3.org/TR/sparql11-query/), [SPARQL 1.1 Update](https://www.w3.org/TR/sparql11-update/) and [SPARQL-star](https://w3c.github.io/rdf-star/cg-spec/). It supports [SPARQL 1.1 Query](https://www.w3.org/TR/sparql11-query/) and [SPARQL 1.1 Update](https://www.w3.org/TR/sparql11-update/).
Support for [SPARQL-star](https://w3c.github.io/rdf-star/cg-spec/#sparql-star) is also available behind the `rdf-star` feature.
This crate is intended to be a building piece for SPARQL implementations in Rust like [Oxigraph](https://oxigraph.org). This crate is intended to be a building piece for SPARQL implementations in Rust like [Oxigraph](https://oxigraph.org).

@ -361,10 +361,15 @@ pub enum Function {
IsLiteral, IsLiteral,
IsNumeric, IsNumeric,
Regex, Regex,
#[cfg(feature = "rdf-star")]
Triple, Triple,
#[cfg(feature = "rdf-star")]
Subject, Subject,
#[cfg(feature = "rdf-star")]
Predicate, Predicate,
#[cfg(feature = "rdf-star")]
Object, Object,
#[cfg(feature = "rdf-star")]
IsTriple, IsTriple,
Custom(NamedNode), Custom(NamedNode),
} }
@ -418,10 +423,15 @@ impl fmt::Display for Function {
Function::IsLiteral => write!(f, "isLITERAL"), Function::IsLiteral => write!(f, "isLITERAL"),
Function::IsNumeric => write!(f, "isNUMERIC"), Function::IsNumeric => write!(f, "isNUMERIC"),
Function::Regex => write!(f, "REGEX"), Function::Regex => write!(f, "REGEX"),
#[cfg(feature = "rdf-star")]
Function::Triple => write!(f, "TRIPLE"), Function::Triple => write!(f, "TRIPLE"),
#[cfg(feature = "rdf-star")]
Function::Subject => write!(f, "SUBJECT"), Function::Subject => write!(f, "SUBJECT"),
#[cfg(feature = "rdf-star")]
Function::Predicate => write!(f, "PREDICATE"), Function::Predicate => write!(f, "PREDICATE"),
#[cfg(feature = "rdf-star")]
Function::Object => write!(f, "OBJECT"), Function::Object => write!(f, "OBJECT"),
#[cfg(feature = "rdf-star")]
Function::IsTriple => write!(f, "isTRIPLE"), Function::IsTriple => write!(f, "isTRIPLE"),
Function::Custom(iri) => iri.fmt(f), Function::Custom(iri) => iri.fmt(f),
} }
@ -656,12 +666,16 @@ impl GraphPattern {
} => { } => {
if let TermPattern::Variable(s) = subject { if let TermPattern::Variable(s) = subject {
vars.insert(s); vars.insert(s);
} else if let TermPattern::Triple(s) = subject { }
#[cfg(feature = "rdf-star")]
if let TermPattern::Triple(s) = subject {
add_triple_pattern_variables(s, vars) add_triple_pattern_variables(s, vars)
} }
if let TermPattern::Variable(o) = object { if let TermPattern::Variable(o) = object {
vars.insert(o); vars.insert(o);
} else if let TermPattern::Triple(o) = object { }
#[cfg(feature = "rdf-star")]
if let TermPattern::Triple(o) = object {
add_triple_pattern_variables(o, vars) add_triple_pattern_variables(o, vars)
} }
} }
@ -703,7 +717,9 @@ impl GraphPattern {
fn add_triple_pattern_variables<'a>(pattern: &'a TriplePattern, vars: &mut BTreeSet<&'a Variable>) { fn add_triple_pattern_variables<'a>(pattern: &'a TriplePattern, vars: &mut BTreeSet<&'a Variable>) {
if let TermPattern::Variable(s) = &pattern.subject { if let TermPattern::Variable(s) = &pattern.subject {
vars.insert(s); vars.insert(s);
} else if let TermPattern::Triple(s) = &pattern.subject { }
#[cfg(feature = "rdf-star")]
if let TermPattern::Triple(s) = &pattern.subject {
add_triple_pattern_variables(s, vars) add_triple_pattern_variables(s, vars)
} }
if let NamedNodePattern::Variable(p) = &pattern.predicate { if let NamedNodePattern::Variable(p) = &pattern.predicate {
@ -711,7 +727,9 @@ fn add_triple_pattern_variables<'a>(pattern: &'a TriplePattern, vars: &mut BTree
} }
if let TermPattern::Variable(o) = &pattern.object { if let TermPattern::Variable(o) = &pattern.object {
vars.insert(o); vars.insert(o);
} else if let TermPattern::Triple(o) = &pattern.object { }
#[cfg(feature = "rdf-star")]
if let TermPattern::Triple(o) = &pattern.object {
add_triple_pattern_variables(o, vars) add_triple_pattern_variables(o, vars)
} }
} }

@ -5,6 +5,8 @@
//! //!
//! This crate is intended to be a building piece for SPARQL implementations in Rust like [Oxigraph](https://oxigraph.org). //! This crate is intended to be a building piece for SPARQL implementations in Rust like [Oxigraph](https://oxigraph.org).
//! //!
//! Support for [SPARQL-star](https://w3c.github.io/rdf-star/cg-spec/) is available behind the `rdf-star` feature.
//!
//! Usage example: //! Usage example:
//! ``` //! ```
//! use spargebra::Query; //! use spargebra::Query;

@ -150,14 +150,20 @@ fn add_to_triple_patterns(
predicate: NamedNodePattern, predicate: NamedNodePattern,
object: AnnotatedTerm, object: AnnotatedTerm,
patterns: &mut Vec<TriplePattern>, patterns: &mut Vec<TriplePattern>,
) { ) -> Result<(), &'static str> {
let triple = TriplePattern::new(subject, predicate, object.term); let triple = TriplePattern::new(subject, predicate, object.term);
#[cfg(feature = "rdf-star")]
for (p, os) in object.annotations { for (p, os) in object.annotations {
for o in os { for o in os {
add_to_triple_patterns(triple.clone().into(), p.clone(), o, patterns) add_to_triple_patterns(triple.clone().into(), p.clone(), o, patterns)?
}
} }
#[cfg(not(feature = "rdf-star"))]
if !object.annotations.is_empty() {
return Err("Embedded triples are only available in SPARQL-star");
} }
patterns.push(triple) patterns.push(triple);
Ok(())
} }
fn add_to_triple_or_path_patterns( fn add_to_triple_or_path_patterns(
@ -229,11 +235,16 @@ fn add_triple_to_triple_or_path_patterns(
patterns: &mut Vec<TripleOrPathPattern>, patterns: &mut Vec<TripleOrPathPattern>,
) -> Result<(), &'static str> { ) -> Result<(), &'static str> {
let triple = TriplePattern::new(subject, predicate, object.term); let triple = TriplePattern::new(subject, predicate, object.term);
#[cfg(feature = "rdf-star")]
for (p, os) in object.annotations { for (p, os) in object.annotations {
for o in os { for o in os {
add_to_triple_or_path_patterns(triple.clone().into(), p.clone(), o, patterns)? add_to_triple_or_path_patterns(triple.clone().into(), p.clone(), o, patterns)?
} }
} }
#[cfg(not(feature = "rdf-star"))]
if !object.annotations.is_empty() {
return Err("Embedded triples are only available in SPARQL-star");
}
patterns.push(triple.into()); patterns.push(triple.into());
Ok(()) Ok(())
} }
@ -1384,7 +1395,10 @@ parser! {
//[65] //[65]
rule DataBlockValue() -> Option<GroundTerm> = rule DataBlockValue() -> Option<GroundTerm> =
t:EmbTriple() { Some(t.into()) } / t:EmbTriple() {?
#[cfg(feature = "rdf-star")]{Ok(Some(t.into()))}
#[cfg(not(feature = "rdf-star"))]{Err("Embedded triples are only available in SPARQL-star")}
} /
i:iri() { Some(i.into()) } / i:iri() { Some(i.into()) } /
l:RDFLiteral() { Some(l.into()) } / l:RDFLiteral() { Some(l.into()) } /
l:NumericLiteral() { Some(l.into()) } / l:NumericLiteral() { Some(l.into()) } /
@ -1440,24 +1454,24 @@ parser! {
//[75] //[75]
rule TriplesSameSubject() -> Vec<TriplePattern> = rule TriplesSameSubject() -> Vec<TriplePattern> =
s:VarOrTermOrEmbTP() _ po:PropertyListNotEmpty() { s:VarOrTermOrEmbTP() _ po:PropertyListNotEmpty() {?
let mut patterns = po.patterns; let mut patterns = po.patterns;
for (p, os) in po.focus { for (p, os) in po.focus {
for o in os { for o in os {
add_to_triple_patterns(s.clone(), p.clone(), o, &mut patterns) add_to_triple_patterns(s.clone(), p.clone(), o, &mut patterns)?
} }
} }
patterns Ok(patterns)
} / } /
s:TriplesNode() _ po:PropertyList() { s:TriplesNode() _ po:PropertyList() {?
let mut patterns = s.patterns; let mut patterns = s.patterns;
patterns.extend(po.patterns); patterns.extend(po.patterns);
for (p, os) in po.focus { for (p, os) in po.focus {
for o in os { for o in os {
add_to_triple_patterns(s.focus.clone(), p.clone(), o, &mut patterns) add_to_triple_patterns(s.focus.clone(), p.clone(), o, &mut patterns)?
} }
} }
patterns Ok(patterns)
} }
//[76] //[76]
@ -1686,18 +1700,18 @@ parser! {
rule TriplesNode() -> FocusedTriplePattern<TermPattern> = Collection() / BlankNodePropertyList() rule TriplesNode() -> FocusedTriplePattern<TermPattern> = Collection() / BlankNodePropertyList()
//[99] //[99]
rule BlankNodePropertyList() -> FocusedTriplePattern<TermPattern> = "[" _ po:PropertyListNotEmpty() _ "]" { rule BlankNodePropertyList() -> FocusedTriplePattern<TermPattern> = "[" _ po:PropertyListNotEmpty() _ "]" {?
let mut patterns = po.patterns; let mut patterns = po.patterns;
let mut bnode = TermPattern::from(bnode()); let mut bnode = TermPattern::from(bnode());
for (p, os) in po.focus { for (p, os) in po.focus {
for o in os { for o in os {
add_to_triple_patterns(bnode.clone(), p.clone(), o, &mut patterns) add_to_triple_patterns(bnode.clone(), p.clone(), o, &mut patterns)?;
} }
} }
FocusedTriplePattern { Ok(FocusedTriplePattern {
focus: bnode, focus: bnode,
patterns patterns
} })
} }
//[100] //[100]
@ -1926,11 +1940,26 @@ parser! {
RegexExpression() / RegexExpression() /
ExistsFunc() / ExistsFunc() /
NotExistsFunc() / NotExistsFunc() /
i("TRIPLE") "(" _ s:Expression() _ "," _ p:Expression() "," _ o:Expression() ")" { Expression::FunctionCall(Function::Triple, vec![s, p, o]) } / i("TRIPLE") "(" _ s:Expression() _ "," _ p:Expression() "," _ o:Expression() ")" {?
i("SUBJECT") "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Subject, vec![e]) } / #[cfg(feature = "rdf-star")]{Ok(Expression::FunctionCall(Function::Triple, vec![s, p, o]))}
i("PREDICATE") "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Predicate, vec![e]) } / #[cfg(not(feature = "rdf-star"))]{Err("The TRIPLE function is only available in SPARQL-star")}
i("OBJECT") "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Object, vec![e]) } / } /
i("isTriple") "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::IsTriple, vec![e]) } i("SUBJECT") "(" _ e:Expression() _ ")" {?
#[cfg(feature = "rdf-star")]{Ok(Expression::FunctionCall(Function::Subject, vec![e]))}
#[cfg(not(feature = "rdf-star"))]{Err("The SUBJECT function is only available in SPARQL-star")}
} /
i("PREDICATE") "(" _ e:Expression() _ ")" {?
#[cfg(feature = "rdf-star")]{Ok(Expression::FunctionCall(Function::Predicate, vec![e]))}
#[cfg(not(feature = "rdf-star"))]{Err("The PREDICATE function is only available in SPARQL-star")}
} /
i("OBJECT") "(" _ e:Expression() _ ")" {?
#[cfg(feature = "rdf-star")]{Ok(Expression::FunctionCall(Function::Object, vec![e]))}
#[cfg(not(feature = "rdf-star"))]{Err("The OBJECT function is only available in SPARQL-star")}
} /
i("isTriple") "(" _ e:Expression() _ ")" {?
#[cfg(feature = "rdf-star")]{Ok(Expression::FunctionCall(Function::IsTriple, vec![e]))}
#[cfg(not(feature = "rdf-star"))]{Err("The isTriple function is only available in SPARQL-star")}
}
//[122] //[122]
rule RegexExpression() -> Expression = rule RegexExpression() -> Expression =
@ -2198,7 +2227,10 @@ parser! {
//[176] //[176]
rule EmbSubjectOrObject() -> TermPattern = rule EmbSubjectOrObject() -> TermPattern =
t:EmbTP() { t.into() } / t:EmbTP() {?
#[cfg(feature = "rdf-star")]{Ok(t.into())}
#[cfg(not(feature = "rdf-star"))]{Err("Embedded triple patterns are only available in SPARQL-star")}
} /
v:Var() { v.into() } / v:Var() { v.into() } /
b:BlankNode() { b.into() } / b:BlankNode() { b.into() } /
i:iri() { i.into() } / i:iri() { i.into() } /
@ -2211,11 +2243,17 @@ parser! {
l:RDFLiteral() { l.into() } / l:RDFLiteral() { l.into() } /
l:NumericLiteral() { l.into() } / l:NumericLiteral() { l.into() } /
l:BooleanLiteral() { l.into() } / l:BooleanLiteral() { l.into() } /
t:EmbTriple() { t.into() } t:EmbTriple() {?
#[cfg(feature = "rdf-star")]{Ok(t.into())}
#[cfg(not(feature = "rdf-star"))]{Err("Embedded triples are only available in SPARQL-star")}
}
//[178] //[178]
rule VarOrTermOrEmbTP() -> TermPattern = rule VarOrTermOrEmbTP() -> TermPattern =
t:EmbTP() { t.into() } / t:EmbTP() {?
#[cfg(feature = "rdf-star")]{Ok(t.into())}
#[cfg(not(feature = "rdf-star"))]{Err("Embedded triple patterns are only available in SPARQL-star")}
} /
v:Var() { v.into() } / v:Var() { v.into() } /
t:GraphTerm() { t.into() } t:GraphTerm() { t.into() }
@ -2226,8 +2264,9 @@ parser! {
rule AnnotationPatternPath() -> FocusedTripleOrPathPattern<Vec<(VariableOrPropertyPath,Vec<AnnotatedTermPath>)>> = "{|" _ a: PropertyListPathNotEmpty() _ "|}" { a } rule AnnotationPatternPath() -> FocusedTripleOrPathPattern<Vec<(VariableOrPropertyPath,Vec<AnnotatedTermPath>)>> = "{|" _ a: PropertyListPathNotEmpty() _ "|}" { a }
//[181] //[181]
rule ExprEmbTP() -> Expression = "<<" _ s:ExprVarOrTerm() _ p:Verb() _ o:ExprVarOrTerm() _ ">>" { rule ExprEmbTP() -> Expression = "<<" _ s:ExprVarOrTerm() _ p:Verb() _ o:ExprVarOrTerm() _ ">>" {?
Expression::FunctionCall(Function::Triple, vec![s, p.into(), o]) #[cfg(feature = "rdf-star")]{Ok(Expression::FunctionCall(Function::Triple, vec![s, p.into(), o]))}
#[cfg(not(feature = "rdf-star"))]{Err("Embedded triples are only available in SPARQL-star")}
} }
//[182] //[182]

@ -139,6 +139,7 @@ impl fmt::Display for Literal {
pub enum Subject { pub enum Subject {
NamedNode(NamedNode), NamedNode(NamedNode),
BlankNode(BlankNode), BlankNode(BlankNode),
#[cfg(feature = "rdf-star")]
Triple(Box<Triple>), Triple(Box<Triple>),
} }
@ -148,6 +149,7 @@ impl fmt::Display for Subject {
match self { match self {
Self::NamedNode(node) => node.fmt(f), Self::NamedNode(node) => node.fmt(f),
Self::BlankNode(node) => node.fmt(f), Self::BlankNode(node) => node.fmt(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => write!( Self::Triple(triple) => write!(
f, f,
"<<{} {} {}>>", "<<{} {} {}>>",
@ -171,6 +173,7 @@ impl From<BlankNode> for Subject {
} }
} }
#[cfg(feature = "rdf-star")]
impl From<Triple> for Subject { impl From<Triple> for Subject {
#[inline] #[inline]
fn from(triple: Triple) -> Self { fn from(triple: Triple) -> Self {
@ -186,6 +189,7 @@ impl TryFrom<TermPattern> for Subject {
match term { match term {
TermPattern::NamedNode(t) => Ok(t.into()), TermPattern::NamedNode(t) => Ok(t.into()),
TermPattern::BlankNode(t) => Ok(t.into()), TermPattern::BlankNode(t) => Ok(t.into()),
#[cfg(feature = "rdf-star")]
TermPattern::Triple(t) => Ok(Triple::try_from(*t)?.into()), TermPattern::Triple(t) => Ok(Triple::try_from(*t)?.into()),
TermPattern::Literal(_) | TermPattern::Variable(_) => Err(()), TermPattern::Literal(_) | TermPattern::Variable(_) => Err(()),
} }
@ -198,6 +202,7 @@ impl TryFrom<TermPattern> for Subject {
#[derive(Eq, PartialEq, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum GroundSubject { pub enum GroundSubject {
NamedNode(NamedNode), NamedNode(NamedNode),
#[cfg(feature = "rdf-star")]
Triple(Box<GroundTriple>), Triple(Box<GroundTriple>),
} }
@ -206,6 +211,7 @@ impl fmt::Display for GroundSubject {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
Self::NamedNode(node) => node.fmt(f), Self::NamedNode(node) => node.fmt(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => write!( Self::Triple(triple) => write!(
f, f,
"<<{} {} {}>>", "<<{} {} {}>>",
@ -222,6 +228,7 @@ impl From<NamedNode> for GroundSubject {
} }
} }
#[cfg(feature = "rdf-star")]
impl From<GroundTriple> for GroundSubject { impl From<GroundTriple> for GroundSubject {
#[inline] #[inline]
fn from(triple: GroundTriple) -> Self { fn from(triple: GroundTriple) -> Self {
@ -237,6 +244,7 @@ impl TryFrom<Subject> for GroundSubject {
match subject { match subject {
Subject::NamedNode(t) => Ok(t.into()), Subject::NamedNode(t) => Ok(t.into()),
Subject::BlankNode(_) => Err(()), Subject::BlankNode(_) => Err(()),
#[cfg(feature = "rdf-star")]
Subject::Triple(t) => Ok(GroundTriple::try_from(*t)?.into()), Subject::Triple(t) => Ok(GroundTriple::try_from(*t)?.into()),
} }
} }
@ -250,6 +258,7 @@ impl TryFrom<GroundTerm> for GroundSubject {
match term { match term {
GroundTerm::NamedNode(t) => Ok(t.into()), GroundTerm::NamedNode(t) => Ok(t.into()),
GroundTerm::Literal(_) => Err(()), GroundTerm::Literal(_) => Err(()),
#[cfg(feature = "rdf-star")]
GroundTerm::Triple(t) => Ok((*t).into()), GroundTerm::Triple(t) => Ok((*t).into()),
} }
} }
@ -265,6 +274,7 @@ pub enum Term {
NamedNode(NamedNode), NamedNode(NamedNode),
BlankNode(BlankNode), BlankNode(BlankNode),
Literal(Literal), Literal(Literal),
#[cfg(feature = "rdf-star")]
Triple(Box<Triple>), Triple(Box<Triple>),
} }
@ -275,6 +285,7 @@ impl fmt::Display for Term {
Self::NamedNode(node) => node.fmt(f), Self::NamedNode(node) => node.fmt(f),
Self::BlankNode(node) => node.fmt(f), Self::BlankNode(node) => node.fmt(f),
Self::Literal(literal) => literal.fmt(f), Self::Literal(literal) => literal.fmt(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => write!( Self::Triple(triple) => write!(
f, f,
"<<{} {} {}>>", "<<{} {} {}>>",
@ -305,6 +316,7 @@ impl From<Literal> for Term {
} }
} }
#[cfg(feature = "rdf-star")]
impl From<Triple> for Term { impl From<Triple> for Term {
#[inline] #[inline]
fn from(triple: Triple) -> Self { fn from(triple: Triple) -> Self {
@ -318,6 +330,7 @@ impl From<Subject> for Term {
match resource { match resource {
Subject::NamedNode(node) => node.into(), Subject::NamedNode(node) => node.into(),
Subject::BlankNode(node) => node.into(), Subject::BlankNode(node) => node.into(),
#[cfg(feature = "rdf-star")]
Subject::Triple(t) => (*t).into(), Subject::Triple(t) => (*t).into(),
} }
} }
@ -332,6 +345,7 @@ impl TryFrom<TermPattern> for Term {
TermPattern::NamedNode(t) => Ok(t.into()), TermPattern::NamedNode(t) => Ok(t.into()),
TermPattern::BlankNode(t) => Ok(t.into()), TermPattern::BlankNode(t) => Ok(t.into()),
TermPattern::Literal(t) => Ok(t.into()), TermPattern::Literal(t) => Ok(t.into()),
#[cfg(feature = "rdf-star")]
TermPattern::Triple(t) => Ok(Triple::try_from(*t)?.into()), TermPattern::Triple(t) => Ok(Triple::try_from(*t)?.into()),
TermPattern::Variable(_) => Err(()), TermPattern::Variable(_) => Err(()),
} }
@ -345,6 +359,7 @@ impl TryFrom<TermPattern> for Term {
pub enum GroundTerm { pub enum GroundTerm {
NamedNode(NamedNode), NamedNode(NamedNode),
Literal(Literal), Literal(Literal),
#[cfg(feature = "rdf-star")]
Triple(Box<GroundTriple>), Triple(Box<GroundTriple>),
} }
@ -354,6 +369,7 @@ impl fmt::Display for GroundTerm {
match self { match self {
Self::NamedNode(node) => node.fmt(f), Self::NamedNode(node) => node.fmt(f),
Self::Literal(literal) => literal.fmt(f), Self::Literal(literal) => literal.fmt(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => write!( Self::Triple(triple) => write!(
f, f,
"<<{} {} {}>>", "<<{} {} {}>>",
@ -377,6 +393,7 @@ impl From<Literal> for GroundTerm {
} }
} }
#[cfg(feature = "rdf-star")]
impl From<GroundTriple> for GroundTerm { impl From<GroundTriple> for GroundTerm {
#[inline] #[inline]
fn from(triple: GroundTriple) -> Self { fn from(triple: GroundTriple) -> Self {
@ -393,6 +410,7 @@ impl TryFrom<Term> for GroundTerm {
Term::NamedNode(t) => Ok(t.into()), Term::NamedNode(t) => Ok(t.into()),
Term::BlankNode(_) => Err(()), Term::BlankNode(_) => Err(()),
Term::Literal(t) => Ok(t.into()), Term::Literal(t) => Ok(t.into()),
#[cfg(feature = "rdf-star")]
Term::Triple(t) => Ok(GroundTriple::try_from(*t)?.into()), Term::Triple(t) => Ok(GroundTriple::try_from(*t)?.into()),
} }
} }
@ -694,6 +712,7 @@ pub enum TermPattern {
NamedNode(NamedNode), NamedNode(NamedNode),
BlankNode(BlankNode), BlankNode(BlankNode),
Literal(Literal), Literal(Literal),
#[cfg(feature = "rdf-star")]
Triple(Box<TriplePattern>), Triple(Box<TriplePattern>),
Variable(Variable), Variable(Variable),
} }
@ -705,6 +724,7 @@ impl fmt::Display for TermPattern {
Self::NamedNode(term) => term.fmt(f), Self::NamedNode(term) => term.fmt(f),
Self::BlankNode(term) => term.fmt(f), Self::BlankNode(term) => term.fmt(f),
Self::Literal(term) => term.fmt(f), Self::Literal(term) => term.fmt(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => write!(f, "<<{}>>", triple), Self::Triple(triple) => write!(f, "<<{}>>", triple),
Self::Variable(var) => var.fmt(f), Self::Variable(var) => var.fmt(f),
} }
@ -732,6 +752,7 @@ impl From<Literal> for TermPattern {
} }
} }
#[cfg(feature = "rdf-star")]
impl From<TriplePattern> for TermPattern { impl From<TriplePattern> for TermPattern {
#[inline] #[inline]
fn from(triple: TriplePattern) -> Self { fn from(triple: TriplePattern) -> Self {
@ -751,6 +772,7 @@ impl From<Subject> for TermPattern {
match subject { match subject {
Subject::NamedNode(node) => node.into(), Subject::NamedNode(node) => node.into(),
Subject::BlankNode(node) => node.into(), Subject::BlankNode(node) => node.into(),
#[cfg(feature = "rdf-star")]
Subject::Triple(t) => TriplePattern::from(*t).into(), Subject::Triple(t) => TriplePattern::from(*t).into(),
} }
} }
@ -763,6 +785,7 @@ impl From<Term> for TermPattern {
Term::NamedNode(node) => node.into(), Term::NamedNode(node) => node.into(),
Term::BlankNode(node) => node.into(), Term::BlankNode(node) => node.into(),
Term::Literal(literal) => literal.into(), Term::Literal(literal) => literal.into(),
#[cfg(feature = "rdf-star")]
Term::Triple(t) => TriplePattern::from(*t).into(), Term::Triple(t) => TriplePattern::from(*t).into(),
} }
} }
@ -832,6 +855,7 @@ impl From<GroundSubject> for GroundTermPattern {
fn from(term: GroundSubject) -> Self { fn from(term: GroundSubject) -> Self {
match term { match term {
GroundSubject::NamedNode(node) => node.into(), GroundSubject::NamedNode(node) => node.into(),
#[cfg(feature = "rdf-star")]
GroundSubject::Triple(triple) => GroundTriplePattern::from(*triple).into(), GroundSubject::Triple(triple) => GroundTriplePattern::from(*triple).into(),
} }
} }
@ -842,6 +866,7 @@ impl From<GroundTerm> for GroundTermPattern {
match term { match term {
GroundTerm::NamedNode(node) => node.into(), GroundTerm::NamedNode(node) => node.into(),
GroundTerm::Literal(literal) => literal.into(), GroundTerm::Literal(literal) => literal.into(),
#[cfg(feature = "rdf-star")]
GroundTerm::Triple(triple) => GroundTriplePattern::from(*triple).into(), GroundTerm::Triple(triple) => GroundTriplePattern::from(*triple).into(),
} }
} }
@ -866,6 +891,7 @@ impl TryFrom<TermPattern> for GroundTermPattern {
TermPattern::NamedNode(named_node) => named_node.into(), TermPattern::NamedNode(named_node) => named_node.into(),
TermPattern::BlankNode(_) => return Err(()), TermPattern::BlankNode(_) => return Err(()),
TermPattern::Literal(literal) => literal.into(), TermPattern::Literal(literal) => literal.into(),
#[cfg(feature = "rdf-star")]
TermPattern::Triple(triple) => GroundTriplePattern::try_from(*triple)?.into(), TermPattern::Triple(triple) => GroundTriplePattern::try_from(*triple)?.into(),
TermPattern::Variable(variable) => variable.into(), TermPattern::Variable(variable) => variable.into(),
}) })

Loading…
Cancel
Save