Allows using oxrdf without RDF-star

pull/190/head
Tpt 3 years ago
parent f5545f1948
commit a16a4108b8
  1. 2
      lib/Cargo.toml
  2. 4
      lib/oxrdf/Cargo.toml
  3. 2
      lib/oxrdf/README.md
  4. 65
      lib/oxrdf/src/dataset.rs
  5. 12
      lib/oxrdf/src/interning.rs
  6. 2
      lib/oxrdf/src/lib.rs
  7. 43
      lib/oxrdf/src/parser.rs
  8. 26
      lib/oxrdf/src/triple.rs

@ -42,7 +42,7 @@ lazy_static = "1"
sophia_api = { version = "0.7", optional = true }
json-event-parser = "0.1"
num_cpus = "1"
oxrdf = { version = "0.1", path="oxrdf" }
oxrdf = { version = "0.1", path="oxrdf", features = ["rdf-star"] }
spargebra = { version = "0.1", path="../spargebra", features = ["rdf-star"] }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]

@ -12,6 +12,10 @@ A library providing basic data structures related to RDF
"""
edition = "2021"
[features]
default = []
rdf-star = []
[dependencies]
rand = "0.8"
oxilangtag = "0.1"

@ -11,6 +11,8 @@ OxRDF is a simple library providing datastructures encoding [RDF 1.1 concepts](h
This crate is intended to be a basic building block of other crates like [Oxigraph](https://crates.io/crates/oxigraph) or [Spargebra](https://crates.io/crates/spargebra).
Support for [RDF-star](https://w3c.github.io/rdf-star/cg-spec/) is available behind the `rdf-star` feature.
Inspired by [RDF/JS](https://rdf.js.org/data-model-spec/) and [Apache Commons RDF](http://commons.apache.org/proper/commons-rdf/).
Usage example:

@ -536,12 +536,16 @@ impl Dataset {
for (g, s, _, o) in &self.gspo {
if let InternedSubject::BlankNode(bnode) = s {
bnodes.insert(*bnode);
} else if let InternedSubject::Triple(triple) = s {
}
#[cfg(feature = "rdf-star")]
if let InternedSubject::Triple(triple) = s {
self.triple_blank_nodes(triple, &mut bnodes);
}
if let InternedTerm::BlankNode(bnode) = o {
bnodes.insert(*bnode);
} else if let InternedTerm::Triple(triple) = o {
}
#[cfg(feature = "rdf-star")]
if let InternedTerm::Triple(triple) = o {
self.triple_blank_nodes(triple, &mut bnodes);
}
if let InternedGraphName::BlankNode(bnode) = g {
@ -551,6 +555,7 @@ impl Dataset {
bnodes
}
#[cfg(feature = "rdf-star")]
fn triple_blank_nodes(&self, triple: &InternedTriple, bnodes: &mut HashSet<InternedBlankNode>) {
if let InternedSubject::BlankNode(bnode) = &triple.subject {
bnodes.insert(*bnode);
@ -633,20 +638,24 @@ impl Dataset {
node: &InternedSubject,
bnodes_hash: &HashMap<InternedBlankNode, u64>,
) -> u64 {
#[cfg(feature = "rdf-star")]
if let InternedSubject::Triple(triple) = node {
return self.hash_triple(triple, bnodes_hash);
}
if let InternedSubject::BlankNode(bnode) = node {
bnodes_hash[bnode]
} else if let InternedSubject::Triple(triple) = node {
self.hash_triple(triple, bnodes_hash)
} else {
Self::hash_tuple(node.decode_from(&self.interner))
}
}
fn hash_term(&self, term: &InternedTerm, bnodes_hash: &HashMap<InternedBlankNode, u64>) -> u64 {
#[cfg(feature = "rdf-star")]
if let InternedTerm::Triple(triple) = term {
return self.hash_triple(triple, bnodes_hash);
}
if let InternedTerm::BlankNode(bnode) = term {
bnodes_hash[bnode]
} else if let InternedTerm::Triple(triple) = term {
self.hash_triple(triple, bnodes_hash)
} else {
Self::hash_tuple(term.decode_from(&self.interner))
}
@ -664,6 +673,7 @@ impl Dataset {
}
}
#[cfg(feature = "rdf-star")]
fn hash_triple(
&self,
triple: &InternedTriple,
@ -738,24 +748,42 @@ impl Dataset {
(
if let InternedSubject::BlankNode(bnode) = s {
InternedSubject::BlankNode(self.map_bnode(bnode, hashes))
} else if let InternedSubject::Triple(triple) = s {
InternedSubject::Triple(Box::new(InternedTriple::encoded_into(
self.label_triple(&triple, hashes).as_ref(),
&mut self.interner,
)))
} else {
s
#[cfg(feature = "rdf-star")]
{
if let InternedSubject::Triple(triple) = s {
InternedSubject::Triple(Box::new(InternedTriple::encoded_into(
self.label_triple(&triple, hashes).as_ref(),
&mut self.interner,
)))
} else {
s
}
}
#[cfg(not(feature = "rdf-star"))]
{
s
}
},
p,
if let InternedTerm::BlankNode(bnode) = o {
InternedTerm::BlankNode(self.map_bnode(bnode, hashes))
} else if let InternedTerm::Triple(triple) = o {
InternedTerm::Triple(Box::new(InternedTriple::encoded_into(
self.label_triple(&triple, hashes).as_ref(),
&mut self.interner,
)))
} else {
o
#[cfg(feature = "rdf-star")]
{
if let InternedTerm::Triple(triple) = o {
InternedTerm::Triple(Box::new(InternedTriple::encoded_into(
self.label_triple(&triple, hashes).as_ref(),
&mut self.interner,
)))
} else {
o
}
}
#[cfg(not(feature = "rdf-star"))]
{
o
}
},
if let InternedGraphName::BlankNode(bnode) = g {
InternedGraphName::BlankNode(self.map_bnode(bnode, hashes))
@ -769,6 +797,7 @@ impl Dataset {
quads
}
#[cfg(feature = "rdf-star")]
fn label_triple(
&mut self,
triple: &InternedTriple,

@ -7,6 +7,7 @@ use std::collections::HashMap;
#[derive(Debug, Default)]
pub struct Interner {
strings: Rodeo,
#[cfg(feature = "rdf-star")]
triples: HashMap<InternedTriple, Triple>,
}
@ -175,6 +176,7 @@ impl InternedLiteral {
pub enum InternedSubject {
NamedNode(InternedNamedNode),
BlankNode(InternedBlankNode),
#[cfg(feature = "rdf-star")]
Triple(Box<InternedTriple>),
}
@ -187,6 +189,7 @@ impl InternedSubject {
SubjectRef::BlankNode(node) => {
Self::BlankNode(InternedBlankNode::encoded_into(node, interner))
}
#[cfg(feature = "rdf-star")]
SubjectRef::Triple(triple) => Self::Triple(Box::new(InternedTriple::encoded_into(
triple.as_ref(),
interner,
@ -202,6 +205,7 @@ impl InternedSubject {
SubjectRef::BlankNode(node) => {
Self::BlankNode(InternedBlankNode::encoded_from(node, interner)?)
}
#[cfg(feature = "rdf-star")]
SubjectRef::Triple(triple) => Self::Triple(Box::new(InternedTriple::encoded_from(
triple.as_ref(),
interner,
@ -213,6 +217,7 @@ impl InternedSubject {
match self {
Self::NamedNode(node) => SubjectRef::NamedNode(node.decode_from(interner)),
Self::BlankNode(node) => SubjectRef::BlankNode(node.decode_from(interner)),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => SubjectRef::Triple(&interner.triples[triple.as_ref()]),
}
}
@ -225,6 +230,7 @@ impl InternedSubject {
match self {
Self::NamedNode(node) => Self::NamedNode(node.next()),
Self::BlankNode(node) => Self::BlankNode(node.next()),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => Self::Triple(Box::new(triple.next())),
}
}
@ -296,6 +302,7 @@ pub enum InternedTerm {
NamedNode(InternedNamedNode),
BlankNode(InternedBlankNode),
Literal(InternedLiteral),
#[cfg(feature = "rdf-star")]
Triple(Box<InternedTriple>),
}
@ -309,6 +316,7 @@ impl InternedTerm {
Self::BlankNode(InternedBlankNode::encoded_into(term, interner))
}
TermRef::Literal(term) => Self::Literal(InternedLiteral::encoded_into(term, interner)),
#[cfg(feature = "rdf-star")]
TermRef::Triple(triple) => Self::Triple(Box::new(InternedTriple::encoded_into(
triple.as_ref(),
interner,
@ -325,6 +333,7 @@ impl InternedTerm {
Self::BlankNode(InternedBlankNode::encoded_from(term, interner)?)
}
TermRef::Literal(term) => Self::Literal(InternedLiteral::encoded_from(term, interner)?),
#[cfg(feature = "rdf-star")]
TermRef::Triple(triple) => Self::Triple(Box::new(InternedTriple::encoded_from(
triple.as_ref(),
interner,
@ -337,6 +346,7 @@ impl InternedTerm {
Self::NamedNode(term) => TermRef::NamedNode(term.decode_from(interner)),
Self::BlankNode(term) => TermRef::BlankNode(term.decode_from(interner)),
Self::Literal(term) => TermRef::Literal(term.decode_from(interner)),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => TermRef::Triple(&interner.triples[triple.as_ref()]),
}
}
@ -350,6 +360,7 @@ impl InternedTerm {
Self::NamedNode(node) => Self::NamedNode(node.next()),
Self::BlankNode(node) => Self::BlankNode(node.next()),
Self::Literal(node) => Self::Literal(node.next()),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => Self::Triple(Box::new(triple.next())),
}
}
@ -366,6 +377,7 @@ pub struct InternedTriple {
pub object: InternedTerm,
}
#[cfg(feature = "rdf-star")]
impl InternedTriple {
pub fn encoded_into(triple: TripleRef<'_>, interner: &mut Interner) -> Self {
let interned_triple = Self {

@ -2,6 +2,8 @@
//!
//! This crate is intended to be a basic building block of other crates like [Oxigraph](https://crates.io/crates/oxigraph) or [Spargebra](https://crates.io/crates/spargebra).
//!
//! Support for [RDF-star](https://w3c.github.io/rdf-star/cg-spec/) is available behind the `rdf-star` feature.
//!
//! Inspired by [RDF/JS](https://rdf.js.org/data-model-spec/) and [Apache Commons RDF](http://commons.apache.org/proper/commons-rdf/).
//!
//! Usage example:

@ -301,24 +301,31 @@ fn read_term(s: &str) -> Result<(Term, &str), TermParseError> {
let (object, remain) = read_term(remain)?;
let remain = remain.trim_start();
if let Some(remain) = remain.strip_prefix(">>") {
Ok((
Triple {
subject: match subject {
Term::NamedNode(s) => s.into(),
Term::BlankNode(s) => s.into(),
Term::Literal(_) => {
return Err(TermParseError::msg(
"Literals are not allowed in subject position",
))
}
Term::Triple(s) => Subject::Triple(s),
},
predicate,
object,
}
.into(),
remain,
))
#[cfg(feature = "rdf-star")]
{
Ok((
Triple {
subject: match subject {
Term::NamedNode(s) => s.into(),
Term::BlankNode(s) => s.into(),
Term::Literal(_) => {
return Err(TermParseError::msg(
"Literals are not allowed in subject position",
))
}
Term::Triple(s) => Subject::Triple(s),
},
predicate,
object,
}
.into(),
remain,
))
}
#[cfg(not(feature = "rdf-star"))]
{
Err(TermParseError::msg("RDF-star is not supported"))
}
} else {
Err(TermParseError::msg(
"Nested triple serialization should be enclosed between << and >>",

@ -157,6 +157,7 @@ impl<'a> From<NamedOrBlankNodeRef<'a>> for NamedOrBlankNode {
pub enum Subject {
NamedNode(NamedNode),
BlankNode(BlankNode),
#[cfg(feature = "rdf-star")]
Triple(Arc<Triple>),
}
@ -171,6 +172,7 @@ impl Subject {
self.as_ref().is_blank_node()
}
#[cfg(feature = "rdf-star")]
#[inline]
pub fn is_triple(&self) -> bool {
self.as_ref().is_triple()
@ -181,6 +183,7 @@ impl Subject {
match self {
Self::NamedNode(node) => SubjectRef::NamedNode(node.as_ref()),
Self::BlankNode(node) => SubjectRef::BlankNode(node.as_ref()),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => SubjectRef::Triple(triple),
}
}
@ -221,6 +224,7 @@ impl From<BlankNodeRef<'_>> for Subject {
}
}
#[cfg(feature = "rdf-star")]
impl From<Triple> for Subject {
#[inline]
fn from(node: Triple) -> Self {
@ -228,6 +232,7 @@ impl From<Triple> for Subject {
}
}
#[cfg(feature = "rdf-star")]
impl From<Arc<Triple>> for Subject {
#[inline]
fn from(node: Arc<Triple>) -> Self {
@ -235,6 +240,7 @@ impl From<Arc<Triple>> for Subject {
}
}
#[cfg(feature = "rdf-star")]
impl From<Box<Triple>> for Subject {
#[inline]
fn from(node: Box<Triple>) -> Self {
@ -242,6 +248,7 @@ impl From<Box<Triple>> for Subject {
}
}
#[cfg(feature = "rdf-star")]
impl From<TripleRef<'_>> for Subject {
#[inline]
fn from(node: TripleRef<'_>) -> Self {
@ -271,6 +278,7 @@ impl From<NamedOrBlankNodeRef<'_>> for Subject {
pub enum SubjectRef<'a> {
NamedNode(NamedNodeRef<'a>),
BlankNode(BlankNodeRef<'a>),
#[cfg(feature = "rdf-star")]
Triple(&'a Triple),
}
@ -285,6 +293,7 @@ impl<'a> SubjectRef<'a> {
matches!(self, Self::BlankNode(_))
}
#[cfg(feature = "rdf-star")]
#[inline]
pub fn is_triple(&self) -> bool {
matches!(self, Self::Triple(_))
@ -295,6 +304,7 @@ impl<'a> SubjectRef<'a> {
match self {
Self::NamedNode(node) => Subject::NamedNode(node.into_owned()),
Self::BlankNode(node) => Subject::BlankNode(node.into_owned()),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => Subject::Triple(Arc::new(triple.clone())),
}
}
@ -306,6 +316,7 @@ impl fmt::Display for SubjectRef<'_> {
match self {
Self::NamedNode(node) => node.fmt(f),
Self::BlankNode(node) => node.fmt(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => write!(f, "<<{}>>", triple),
}
}
@ -339,6 +350,7 @@ impl<'a> From<&'a BlankNode> for SubjectRef<'a> {
}
}
#[cfg(feature = "rdf-star")]
impl<'a> From<&'a Triple> for SubjectRef<'a> {
#[inline]
fn from(node: &'a Triple) -> Self {
@ -384,6 +396,7 @@ pub enum Term {
NamedNode(NamedNode),
BlankNode(BlankNode),
Literal(Literal),
#[cfg(feature = "rdf-star")]
Triple(Arc<Triple>),
}
@ -403,6 +416,7 @@ impl Term {
self.as_ref().is_literal()
}
#[cfg(feature = "rdf-star")]
#[inline]
pub fn is_triple(&self) -> bool {
self.as_ref().is_triple()
@ -414,6 +428,7 @@ impl Term {
Self::NamedNode(node) => TermRef::NamedNode(node.as_ref()),
Self::BlankNode(node) => TermRef::BlankNode(node.as_ref()),
Self::Literal(literal) => TermRef::Literal(literal.as_ref()),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => TermRef::Triple(triple),
}
}
@ -468,6 +483,7 @@ impl From<LiteralRef<'_>> for Term {
}
}
#[cfg(feature = "rdf-star")]
impl From<Triple> for Term {
#[inline]
fn from(triple: Triple) -> Self {
@ -475,6 +491,7 @@ impl From<Triple> for Term {
}
}
#[cfg(feature = "rdf-star")]
impl From<Arc<Triple>> for Term {
#[inline]
fn from(node: Arc<Triple>) -> Self {
@ -482,6 +499,7 @@ impl From<Arc<Triple>> for Term {
}
}
#[cfg(feature = "rdf-star")]
impl From<Box<Triple>> for Term {
#[inline]
fn from(node: Box<Triple>) -> Self {
@ -489,6 +507,7 @@ impl From<Box<Triple>> for Term {
}
}
#[cfg(feature = "rdf-star")]
impl From<TripleRef<'_>> for Term {
#[inline]
fn from(triple: TripleRef<'_>) -> Self {
@ -519,6 +538,7 @@ impl From<Subject> for Term {
match node {
Subject::NamedNode(node) => node.into(),
Subject::BlankNode(node) => node.into(),
#[cfg(feature = "rdf-star")]
Subject::Triple(triple) => Self::Triple(triple),
}
}
@ -538,6 +558,7 @@ pub enum TermRef<'a> {
NamedNode(NamedNodeRef<'a>),
BlankNode(BlankNodeRef<'a>),
Literal(LiteralRef<'a>),
#[cfg(feature = "rdf-star")]
Triple(&'a Triple),
}
@ -557,6 +578,7 @@ impl<'a> TermRef<'a> {
matches!(self, Self::Literal(_))
}
#[cfg(feature = "rdf-star")]
#[inline]
pub fn is_triple(&self) -> bool {
matches!(self, Self::Triple(_))
@ -568,6 +590,7 @@ impl<'a> TermRef<'a> {
Self::NamedNode(node) => Term::NamedNode(node.into_owned()),
Self::BlankNode(node) => Term::BlankNode(node.into_owned()),
Self::Literal(literal) => Term::Literal(literal.into_owned()),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => Term::Triple(Arc::new(triple.clone())),
}
}
@ -580,6 +603,7 @@ impl fmt::Display for TermRef<'_> {
Self::NamedNode(node) => node.fmt(f),
Self::BlankNode(node) => node.fmt(f),
Self::Literal(literal) => literal.fmt(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => {
write!(f, "<<{}>>", triple)
}
@ -629,6 +653,7 @@ impl<'a> From<&'a Literal> for TermRef<'a> {
}
}
#[cfg(feature = "rdf-star")]
impl<'a> From<&'a Triple> for TermRef<'a> {
#[inline]
fn from(node: &'a Triple) -> Self {
@ -659,6 +684,7 @@ impl<'a> From<SubjectRef<'a>> for TermRef<'a> {
match node {
SubjectRef::NamedNode(node) => node.into(),
SubjectRef::BlankNode(node) => node.into(),
#[cfg(feature = "rdf-star")]
SubjectRef::Triple(triple) => triple.into(),
}
}

Loading…
Cancel
Save