Adds borrowed data structures for RDF terms

pull/46/head
Tpt 4 years ago
parent d3d78b9713
commit 8bc84b2820
  1. 2
      js/src/model.rs
  2. 18
      js/src/store.rs
  3. 1
      lib/Cargo.toml
  4. 10
      lib/src/io/write.rs
  5. 2
      lib/src/lib.rs
  6. 207
      lib/src/model/blank_node.rs
  7. 294
      lib/src/model/literal.rs
  8. 11
      lib/src/model/mod.rs
  9. 119
      lib/src/model/named_node.rs
  10. 663
      lib/src/model/triple.rs
  11. 264
      lib/src/model/vocab.rs
  12. 12
      lib/src/sparql/algebra.rs
  13. 9
      lib/src/sparql/eval.rs
  14. 34
      lib/src/sparql/parser.rs
  15. 13
      lib/src/sparql/plan_builder.rs
  16. 46
      lib/src/store/memory.rs
  17. 69
      lib/src/store/mod.rs
  18. 101
      lib/src/store/numeric_encoder.rs
  19. 106
      lib/src/store/rocksdb.rs
  20. 106
      lib/src/store/sled.rs
  21. 8
      python/src/memory_store.rs
  22. 2
      python/src/model.rs
  23. 8
      python/src/sled_store.rs
  24. 1
      testsuite/Cargo.toml
  25. 73
      testsuite/src/manifest.rs
  26. 128
      testsuite/src/sparql_evaluator.rs
  27. 115
      testsuite/src/vocab.rs
  28. 8
      wikibase/src/loader.rs

@ -246,7 +246,7 @@ impl JsLiteral {
#[wasm_bindgen(getter)]
pub fn datatype(&self) -> JsNamedNode {
self.inner.datatype().clone().into()
self.inner.datatype().into_owned().into()
}
pub fn equals(&self, other: &JsValue) -> bool {

@ -3,10 +3,10 @@ use crate::model::*;
use crate::utils::to_err;
use js_sys::{Array, Map};
use oxigraph::io::{DatasetFormat, GraphFormat};
use oxigraph::model::GraphName;
use oxigraph::model::*;
use oxigraph::sparql::{QueryOptions, QueryResult};
use oxigraph::MemoryStore;
use std::convert::TryInto;
use std::convert::{TryFrom, TryInto};
use std::io::Cursor;
use wasm_bindgen::prelude::*;
@ -74,25 +74,29 @@ impl JsMemoryStore {
} else {
None
}
.as_ref(),
.as_ref()
.map(|t: &NamedOrBlankNode| t.into()),
if let Some(predicate) = self.from_js.to_optional_term(predicate)? {
Some(predicate.try_into()?)
Some(NamedNode::try_from(predicate)?)
} else {
None
}
.as_ref(),
.as_ref()
.map(|t: &NamedNode| t.into()),
if let Some(object) = self.from_js.to_optional_term(object)? {
Some(object.try_into()?)
} else {
None
}
.as_ref(),
.as_ref()
.map(|t: &Term| t.into()),
if let Some(graph_name) = self.from_js.to_optional_term(graph_name)? {
Some(graph_name.try_into()?)
} else {
None
}
.as_ref(),
.as_ref()
.map(|t: &GraphName| t.into()),
)
.map(|v| JsQuad::from(v).into())
.collect::<Vec<_>>()

@ -16,7 +16,6 @@ edition = "2018"
all-features = true
[dependencies]
lazy_static = "1"
rocksdb = { version = "0.14", optional = true }
sled = { version = "0.34", optional = true }
quick-xml = "0.18"

@ -88,7 +88,8 @@ enum TripleWriterKind<W: Write> {
}
impl<W: Write> TripleWriter<W> {
pub fn write(&mut self, triple: &Triple) -> Result<(), io::Error> {
pub fn write<'a>(&mut self, triple: impl Into<TripleRef<'a>>) -> Result<(), io::Error> {
let triple = triple.into();
match &mut self.formatter {
TripleWriterKind::NTriples(formatter) => formatter.format(&triple.into())?,
TripleWriterKind::Turtle(formatter) => formatter.format(&triple.into())?,
@ -187,10 +188,11 @@ enum QuadWriterKind<W: Write> {
}
impl<W: Write> QuadWriter<W> {
pub fn write(&mut self, triple: &Quad) -> Result<(), io::Error> {
pub fn write<'a>(&mut self, quad: impl Into<QuadRef<'a>>) -> Result<(), io::Error> {
let quad = quad.into();
match &mut self.formatter {
QuadWriterKind::NQuads(formatter) => formatter.format(&triple.into())?,
QuadWriterKind::TriG(formatter) => formatter.format(&triple.into())?,
QuadWriterKind::NQuads(formatter) => formatter.format(&quad.into())?,
QuadWriterKind::TriG(formatter) => formatter.format(&quad.into())?,
}
Ok(())
}

@ -27,7 +27,7 @@
//! store.insert(quad.clone());
//!
//! // quad filter
//! let results: Vec<Quad> = store.quads_for_pattern(Some(&ex.clone().into()), None, None, None).collect();
//! let results: Vec<Quad> = store.quads_for_pattern(Some(ex.as_ref().into()), None, None, None).collect();
//! assert_eq!(vec![quad], results);
//!
//! // SPARQL query

@ -5,7 +5,7 @@ use std::fmt;
use std::io::Write;
use std::str;
/// An RDF [blank node](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node).
/// An owned RDF [blank node](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node).
///
/// The common way to create a new blank node is to use the `BlankNode::default` trait method.
///
@ -28,7 +28,7 @@ pub struct BlankNode(BlankNodeContent);
#[derive(PartialEq, Eq, Debug, Clone, Hash)]
enum BlankNodeContent {
Named(String),
Anonymous { id: u128, str: [u8; 32] },
Anonymous { id: u128, str: IdStr },
}
impl BlankNode {
@ -52,13 +52,8 @@ impl BlankNode {
/// Except if you really know what you do, you should use [`new`](#method.new).
pub fn new_unchecked(id: impl Into<String>) -> Self {
let id = id.into();
if let Ok(numerical_id) = u128::from_str_radix(&id, 16) {
let result = Self::new_from_unique_id(numerical_id);
if result.as_str() == id {
result
} else {
Self(BlankNodeContent::Named(id))
}
if let Some(numerical_id) = to_integer_id(&id) {
Self::new_from_unique_id(numerical_id)
} else {
Self(BlankNodeContent::Named(id))
}
@ -69,19 +64,17 @@ impl BlankNode {
/// In most cases, it is much more convenient to create a blank node using `BlankNode::default()`.
pub fn new_from_unique_id(id: impl Into<u128>) -> Self {
let id = id.into();
let mut str = [0; 32];
write!(&mut str[..], "{:x}", id).unwrap();
Self(BlankNodeContent::Anonymous { id, str })
Self(BlankNodeContent::Anonymous {
id,
str: IdStr::new(id),
})
}
/// Returns the underlying ID of this blank node
pub fn as_str(&self) -> &str {
match &self.0 {
BlankNodeContent::Named(id) => id,
BlankNodeContent::Anonymous { str, .. } => {
let len = str.iter().position(|x| x == &0).unwrap_or(32);
str::from_utf8(&str[..len]).unwrap()
}
BlankNodeContent::Anonymous { str, .. } => str.as_str(),
}
}
@ -89,25 +82,24 @@ impl BlankNode {
pub fn into_string(self) -> String {
match self.0 {
BlankNodeContent::Named(id) => id,
BlankNodeContent::Anonymous { str, .. } => {
let len = str.iter().position(|x| x == &0).unwrap_or(32);
str::from_utf8(&str[..len]).unwrap().to_owned()
}
BlankNodeContent::Anonymous { str, .. } => str.as_str().to_owned(),
}
}
/// Returns the internal numerical ID of this blank node, if it exists
pub(crate) fn id(&self) -> Option<u128> {
match self.0 {
BlankNodeContent::Named(_) => None,
BlankNodeContent::Anonymous { id, .. } => Some(id),
}
pub fn as_ref(&self) -> BlankNodeRef<'_> {
BlankNodeRef(match &self.0 {
BlankNodeContent::Named(id) => BlankNodeRefContent::Named(id.as_str()),
BlankNodeContent::Anonymous { id, str } => BlankNodeRefContent::Anonymous {
id: *id,
str: str.as_str(),
},
})
}
}
impl fmt::Display for BlankNode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
rio::BlankNode::from(self).fmt(f)
self.as_ref().fmt(f)
}
}
@ -118,12 +110,140 @@ impl Default for BlankNode {
}
}
impl<'a> From<&'a BlankNode> for rio::BlankNode<'a> {
/// A borrowed RDF [blank node](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node).
///
/// The common way to create a new blank node is to use the `BlankNode::default` trait method.
///
/// It is also possible to create a blank node from a blank node identifier using the `BlankNodeRef::new` method.
/// The blank node identifier must be valid according to N-Triples, Turtle and SPARQL grammars.
///
/// The default string formatter is returning a N-Triples, Turtle and SPARQL compatible representation:
/// ```
/// use oxigraph::model::BlankNodeRef;
///
/// assert_eq!(
/// "_:a122",
/// BlankNodeRef::new("a122")?.to_string()
/// );
/// # Result::<_,oxigraph::model::BlankNodeIdParseError>::Ok(())
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub struct BlankNodeRef<'a>(BlankNodeRefContent<'a>);
#[derive(PartialEq, Eq, Debug, Clone, Copy, Hash)]
enum BlankNodeRefContent<'a> {
Named(&'a str),
Anonymous { id: u128, str: &'a str },
}
impl<'a> BlankNodeRef<'a> {
/// Creates a blank node from a unique identifier.
///
/// The blank node identifier must be valid according to N-Triples, Turtle and SPARQL grammars.
///
/// In most cases, it is much more convenient to create a blank node using `BlankNode::default()`.
/// `BlankNode::default()` creates a random ID that could be easily inlined by Oxigraph stores.
pub fn new(id: &'a str) -> Result<Self, BlankNodeIdParseError> {
validate_blank_node_identifier(id)?;
Ok(Self::new_unchecked(id))
}
/// Creates a blank node from a unique identifier without validation.
///
/// It is the caller's responsibility to ensure that `id` is a valid blank node identifier
/// according to N-Triples, Turtle and SPARQL grammars.
///
/// Except if you really know what you do, you should use [`new`](#method.new).
pub fn new_unchecked(id: &'a str) -> Self {
if let Some(numerical_id) = to_integer_id(id) {
Self(BlankNodeRefContent::Anonymous {
id: numerical_id,
str: id,
})
} else {
Self(BlankNodeRefContent::Named(id))
}
}
/// Returns the underlying ID of this blank node
pub fn as_str(self) -> &'a str {
match self.0 {
BlankNodeRefContent::Named(id) => id,
BlankNodeRefContent::Anonymous { str, .. } => str,
}
}
/// Returns the internal numerical ID of this blank node, if it exists
pub(crate) fn id(&self) -> Option<u128> {
match self.0 {
BlankNodeRefContent::Named(_) => None,
BlankNodeRefContent::Anonymous { id, .. } => Some(id),
}
}
pub fn into_owned(self) -> BlankNode {
BlankNode(match self.0 {
BlankNodeRefContent::Named(id) => BlankNodeContent::Named(id.to_owned()),
BlankNodeRefContent::Anonymous { id, .. } => BlankNodeContent::Anonymous {
id,
str: IdStr::new(id),
},
})
}
}
impl fmt::Display for BlankNodeRef<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
rio::BlankNode::from(*self).fmt(f)
}
}
impl<'a> From<&'a BlankNode> for BlankNodeRef<'a> {
fn from(node: &'a BlankNode) -> Self {
node.as_ref()
}
}
impl<'a> From<BlankNodeRef<'a>> for BlankNode {
fn from(node: BlankNodeRef<'a>) -> Self {
node.into_owned()
}
}
impl<'a> From<BlankNodeRef<'a>> for rio::BlankNode<'a> {
fn from(node: BlankNodeRef<'a>) -> Self {
rio::BlankNode { id: node.as_str() }
}
}
impl PartialEq<BlankNode> for BlankNodeRef<'_> {
fn eq(&self, other: &BlankNode) -> bool {
*self == other.as_ref()
}
}
impl PartialEq<BlankNodeRef<'_>> for BlankNode {
fn eq(&self, other: &BlankNodeRef<'_>) -> bool {
self.as_ref() == *other
}
}
#[derive(PartialEq, Eq, Debug, Clone, Hash)]
struct IdStr([u8; 32]);
impl IdStr {
fn new(id: u128) -> Self {
let mut str = [0; 32];
write!(&mut str[..], "{:x}", id).unwrap();
Self(str)
}
fn as_str(&self) -> &str {
let len = self.0.iter().position(|x| x == &0).unwrap_or(32);
str::from_utf8(&self.0[..len]).unwrap()
}
}
fn validate_blank_node_identifier(id: &str) -> Result<(), BlankNodeIdParseError> {
let mut chars = id.chars();
let front = chars.next().ok_or(BlankNodeIdParseError {})?;
@ -183,6 +303,25 @@ fn validate_blank_node_identifier(id: &str) -> Result<(), BlankNodeIdParseError>
}
}
fn to_integer_id(id: &str) -> Option<u128> {
let digits = id.as_bytes();
let mut value: u128 = 0;
if let None | Some(b'0') = digits.first() {
return None; // No empty string or leading zeros
}
for digit in digits {
value = value.checked_mul(16)?.checked_add(
match *digit {
b'0'..=b'9' => digit - b'0',
b'a'..=b'f' => digit - b'a' + 10,
_ => return None,
}
.into(),
)?;
}
Some(value)
}
/// An error raised during `BlankNode` validation.
#[allow(missing_copy_implementations)]
#[derive(Debug)]
@ -234,4 +373,16 @@ mod test {
BlankNode::new_from_unique_id(0x100a_u128)
);
}
#[test]
fn test_equals() {
assert_eq!(
BlankNode::new("100a").unwrap(),
BlankNodeRef::new("100a").unwrap()
);
assert_eq!(
BlankNode::new("zzz").unwrap(),
BlankNodeRef::new("zzz").unwrap()
);
}
}

@ -2,13 +2,14 @@ use crate::model::named_node::NamedNode;
use crate::model::vocab::rdf;
use crate::model::vocab::xsd;
use crate::model::xsd::*;
use crate::model::NamedNodeRef;
use oxilangtag::{LanguageTag, LanguageTagParseError};
use rio_api::model as rio;
use std::borrow::Cow;
use std::fmt;
use std::option::Option;
/// An RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal)
/// An owned RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal)
///
/// The default string formatter is returning a N-Triples, Turtle and SPARQL compatible representation:
/// ```
@ -23,7 +24,7 @@ use std::option::Option;
///
/// assert_eq!(
/// "\"1999-01-01\"^^<http://www.w3.org/2001/XMLSchema#date>",
/// Literal::new_typed_literal("1999-01-01", xsd::DATE.clone()).to_string()
/// Literal::new_typed_literal("1999-01-01", xsd::DATE).to_string()
/// );
///
/// assert_eq!(
@ -52,7 +53,7 @@ impl Literal {
pub fn new_typed_literal(value: impl Into<String>, datatype: impl Into<NamedNode>) -> Self {
let value = value.into();
let datatype = datatype.into();
Literal(if datatype == *xsd::STRING {
Literal(if datatype == xsd::STRING {
LiteralContent::String(value)
} else {
LiteralContent::TypedLiteral { value, datatype }
@ -66,10 +67,10 @@ impl Literal {
) -> Result<Self, LanguageTagParseError> {
let mut language = language.into();
language.make_ascii_lowercase();
Ok(Literal(LiteralContent::LanguageTaggedString {
value: value.into(),
language: LanguageTag::parse(language)?.into_inner(),
}))
Ok(Self::new_language_tagged_literal_unchecked(
value,
LanguageTag::parse(language)?.into_inner(),
))
}
/// Builds an RDF [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string)
@ -92,11 +93,7 @@ impl Literal {
/// The literal [lexical form](https://www.w3.org/TR/rdf11-concepts/#dfn-lexical-form)
pub fn value(&self) -> &str {
match &self.0 {
LiteralContent::String(value)
| LiteralContent::LanguageTaggedString { value, .. }
| LiteralContent::TypedLiteral { value, .. } => value,
}
self.as_ref().value()
}
/// The literal [language tag](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tag) if it is a [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string).
@ -104,33 +101,36 @@ impl Literal {
/// Language tags are defined by the [BCP47](https://tools.ietf.org/html/bcp47).
/// They are normalized to lowercase by this implementation.
pub fn language(&self) -> Option<&str> {
match &self.0 {
LiteralContent::LanguageTaggedString { language, .. } => Some(language),
_ => None,
}
self.as_ref().language()
}
/// The literal [datatype](https://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri).
///
/// The datatype of [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string) is always [rdf:langString](http://www.w3.org/1999/02/22-rdf-syntax-ns#langString).
/// The datatype of [simple literals](https://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal) is [xsd:string](http://www.w3.org/2001/XMLSchema#string).
pub fn datatype(&self) -> &NamedNode {
match &self.0 {
LiteralContent::String(_) => &xsd::STRING,
LiteralContent::LanguageTaggedString { .. } => &rdf::LANG_STRING,
LiteralContent::TypedLiteral { datatype, .. } => datatype,
}
pub fn datatype(&self) -> NamedNodeRef<'_> {
self.as_ref().datatype()
}
/// Checks if this lieteral could be seen as an RDF 1.0 [plain literal](https://www.w3.org/TR/rdf-concepts/#dfn-plain-literal).
/// Checks if this literal could be seen as an RDF 1.0 [plain literal](https://www.w3.org/TR/rdf-concepts/#dfn-plain-literal).
///
/// It returns true if the literal is a [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string)
/// or has the datatype [xsd:string](http://www.w3.org/2001/XMLSchema#string).
pub fn is_plain(&self) -> bool {
match self.0 {
LiteralContent::String(_) | LiteralContent::LanguageTaggedString { .. } => true,
_ => false,
self.as_ref().is_plain()
}
pub fn as_ref(&self) -> LiteralRef<'_> {
LiteralRef(match &self.0 {
LiteralContent::String(value) => LiteralRefContent::String(value),
LiteralContent::LanguageTaggedString { value, language } => {
LiteralRefContent::LanguageTaggedString { value, language }
}
LiteralContent::TypedLiteral { value, datatype } => LiteralRefContent::TypedLiteral {
value,
datatype: datatype.as_ref(),
},
})
}
/// Extract components from this literal
@ -147,7 +147,7 @@ impl Literal {
impl fmt::Display for Literal {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
rio::Literal::from(self).fmt(f)
self.as_ref().fmt(f)
}
}
@ -173,7 +173,7 @@ impl From<bool> for Literal {
fn from(value: bool) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::BOOLEAN.clone(),
datatype: xsd::BOOLEAN.into(),
})
}
}
@ -182,7 +182,7 @@ impl From<i128> for Literal {
fn from(value: i128) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::INTEGER.clone(),
datatype: xsd::INTEGER.into(),
})
}
}
@ -191,7 +191,7 @@ impl From<i64> for Literal {
fn from(value: i64) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::INTEGER.clone(),
datatype: xsd::INTEGER.into(),
})
}
}
@ -200,7 +200,7 @@ impl From<i32> for Literal {
fn from(value: i32) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::INTEGER.clone(),
datatype: xsd::INTEGER.into(),
})
}
}
@ -209,7 +209,7 @@ impl From<i16> for Literal {
fn from(value: i16) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::INTEGER.clone(),
datatype: xsd::INTEGER.into(),
})
}
}
@ -218,7 +218,7 @@ impl From<u64> for Literal {
fn from(value: u64) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::INTEGER.clone(),
datatype: xsd::INTEGER.into(),
})
}
}
@ -227,7 +227,7 @@ impl From<u32> for Literal {
fn from(value: u32) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::INTEGER.clone(),
datatype: xsd::INTEGER.into(),
})
}
}
@ -236,7 +236,7 @@ impl From<u16> for Literal {
fn from(value: u16) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::INTEGER.clone(),
datatype: xsd::INTEGER.into(),
})
}
}
@ -245,7 +245,7 @@ impl From<f32> for Literal {
fn from(value: f32) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::FLOAT.clone(),
datatype: xsd::FLOAT.into(),
})
}
}
@ -254,7 +254,7 @@ impl From<f64> for Literal {
fn from(value: f64) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::DOUBLE.clone(),
datatype: xsd::DOUBLE.into(),
})
}
}
@ -263,7 +263,7 @@ impl From<Decimal> for Literal {
fn from(value: Decimal) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::DECIMAL.clone(),
datatype: xsd::DECIMAL.into(),
})
}
}
@ -272,7 +272,7 @@ impl From<Date> for Literal {
fn from(value: Date) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::DATE.clone(),
datatype: xsd::DATE.into(),
})
}
}
@ -281,7 +281,7 @@ impl From<Time> for Literal {
fn from(value: Time) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::TIME.clone(),
datatype: xsd::TIME.into(),
})
}
}
@ -290,7 +290,7 @@ impl From<DateTime> for Literal {
fn from(value: DateTime) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::DATE_TIME.clone(),
datatype: xsd::DATE_TIME.into(),
})
}
}
@ -299,7 +299,7 @@ impl From<Duration> for Literal {
fn from(value: Duration) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::DURATION.clone(),
datatype: xsd::DURATION.into(),
})
}
}
@ -308,7 +308,7 @@ impl From<YearMonthDuration> for Literal {
fn from(value: YearMonthDuration) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::YEAR_MONTH_DURATION.clone(),
datatype: xsd::YEAR_MONTH_DURATION.into(),
})
}
}
@ -316,32 +316,196 @@ impl From<DayTimeDuration> for Literal {
fn from(value: DayTimeDuration) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::DAY_TIME_DURATION.clone(),
datatype: xsd::DAY_TIME_DURATION.into(),
})
}
}
impl<'a> From<&'a Literal> for rio::Literal<'a> {
fn from(literal: &'a Literal) -> Self {
if literal.is_plain() {
literal.language().map_or_else(
|| rio::Literal::Simple {
value: literal.value(),
/// A borrowed RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal)
///
/// The default string formatter is returning a N-Triples, Turtle and SPARQL compatible representation:
/// ```
/// # use oxilangtag::LanguageTagParseError;
/// use oxigraph::model::LiteralRef;
/// use oxigraph::model::vocab::xsd;
///
/// assert_eq!(
/// "\"foo\\nbar\"",
/// LiteralRef::new_simple_literal("foo\nbar").to_string()
/// );
///
/// assert_eq!(
/// "\"1999-01-01\"^^<http://www.w3.org/2001/XMLSchema#date>",
/// LiteralRef::new_typed_literal("1999-01-01", xsd::DATE).to_string()
/// );
/// # Result::<(), LanguageTagParseError>::Ok(())
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub struct LiteralRef<'a>(LiteralRefContent<'a>);
#[derive(PartialEq, Eq, Debug, Clone, Copy, Hash)]
enum LiteralRefContent<'a> {
String(&'a str),
LanguageTaggedString {
value: &'a str,
language: &'a str,
},
|lang| rio::Literal::LanguageTaggedString {
value: literal.value(),
language: lang,
TypedLiteral {
value: &'a str,
datatype: NamedNodeRef<'a>,
},
)
}
impl<'a> LiteralRef<'a> {
/// Builds an RDF [simple literal](https://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal)
pub fn new_simple_literal(value: &'a str) -> Self {
LiteralRef(LiteralRefContent::String(value))
}
/// Builds an RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal) with a [datatype](https://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri)
pub fn new_typed_literal(value: &'a str, datatype: impl Into<NamedNodeRef<'a>>) -> Self {
let datatype = datatype.into();
LiteralRef(if datatype == xsd::STRING {
LiteralRefContent::String(value)
} else {
rio::Literal::Typed {
value: literal.value(),
datatype: literal.datatype().into(),
LiteralRefContent::TypedLiteral { value, datatype }
})
}
/// Builds an RDF [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string)
///
/// It is the responsibility of the caller to check that `language`
/// is valid [BCP47](https://tools.ietf.org/html/bcp47) language tag,
/// and is lowercase.
///
/// Except if you really know what you do,
/// you should use [`new_language_tagged_literal`](#method.new_language_tagged_literal).
pub fn new_language_tagged_literal_unchecked(value: &'a str, language: &'a str) -> Self {
LiteralRef(LiteralRefContent::LanguageTaggedString { value, language })
}
/// The literal [lexical form](https://www.w3.org/TR/rdf11-concepts/#dfn-lexical-form)
pub fn value(self) -> &'a str {
match self.0 {
LiteralRefContent::String(value)
| LiteralRefContent::LanguageTaggedString { value, .. }
| LiteralRefContent::TypedLiteral { value, .. } => value,
}
}
/// The literal [language tag](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tag) if it is a [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string).
///
/// Language tags are defined by the [BCP47](https://tools.ietf.org/html/bcp47).
/// They are normalized to lowercase by this implementation.
pub fn language(self) -> Option<&'a str> {
match self.0 {
LiteralRefContent::LanguageTaggedString { language, .. } => Some(language),
_ => None,
}
}
/// The literal [datatype](https://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri).
///
/// The datatype of [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string) is always [rdf:langString](http://www.w3.org/1999/02/22-rdf-syntax-ns#langString).
/// The datatype of [simple literals](https://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal) is [xsd:string](http://www.w3.org/2001/XMLSchema#string).
pub fn datatype(self) -> NamedNodeRef<'a> {
match self.0 {
LiteralRefContent::String(_) => xsd::STRING,
LiteralRefContent::LanguageTaggedString { .. } => rdf::LANG_STRING,
LiteralRefContent::TypedLiteral { datatype, .. } => datatype,
}
}
/// Checks if this literal could be seen as an RDF 1.0 [plain literal](https://www.w3.org/TR/rdf-concepts/#dfn-plain-literal).
///
/// It returns true if the literal is a [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string)
/// or has the datatype [xsd:string](http://www.w3.org/2001/XMLSchema#string).
pub fn is_plain(self) -> bool {
match self.0 {
LiteralRefContent::String(_) | LiteralRefContent::LanguageTaggedString { .. } => true,
_ => false,
}
}
pub fn into_owned(self) -> Literal {
Literal(match self.0 {
LiteralRefContent::String(value) => LiteralContent::String(value.to_owned()),
LiteralRefContent::LanguageTaggedString { value, language } => {
LiteralContent::LanguageTaggedString {
value: value.to_owned(),
language: language.to_owned(),
}
}
LiteralRefContent::TypedLiteral { value, datatype } => LiteralContent::TypedLiteral {
value: value.to_owned(),
datatype: datatype.into_owned(),
},
})
}
/// Extract components from this literal
pub fn destruct(self) -> (&'a str, Option<NamedNodeRef<'a>>, Option<&'a str>) {
match self.0 {
LiteralRefContent::String(s) => (s, None, None),
LiteralRefContent::LanguageTaggedString { value, language } => {
(value, None, Some(language))
}
LiteralRefContent::TypedLiteral { value, datatype } => (value, Some(datatype), None),
}
}
}
impl fmt::Display for LiteralRef<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
rio::Literal::from(*self).fmt(f)
}
}
impl<'a> From<&'a Literal> for LiteralRef<'a> {
fn from(node: &'a Literal) -> Self {
node.as_ref()
}
}
impl<'a> From<LiteralRef<'a>> for Literal {
fn from(node: LiteralRef<'a>) -> Self {
node.into_owned()
}
}
impl<'a> From<LiteralRef<'a>> for rio::Literal<'a> {
fn from(literal: LiteralRef<'a>) -> Self {
match literal.0 {
LiteralRefContent::String(value) => rio::Literal::Simple { value },
LiteralRefContent::LanguageTaggedString { value, language } => {
rio::Literal::LanguageTaggedString { value, language }
}
LiteralRefContent::TypedLiteral { value, datatype } => rio::Literal::Typed {
value,
datatype: datatype.into(),
},
}
}
}
impl<'a> From<&'a str> for LiteralRef<'a> {
fn from(value: &'a str) -> Self {
LiteralRef(LiteralRefContent::String(value))
}
}
impl PartialEq<Literal> for LiteralRef<'_> {
fn eq(&self, other: &Literal) -> bool {
*self == other.as_ref()
}
}
impl PartialEq<LiteralRef<'_>> for Literal {
fn eq(&self, other: &LiteralRef<'_>) -> bool {
self.as_ref() == *other
}
}
#[cfg(test)]
mod test {
use super::*;
@ -350,7 +514,19 @@ mod test {
fn test_simple_literal_equality() {
assert_eq!(
Literal::new_simple_literal("foo"),
Literal::new_typed_literal("foo", xsd::STRING.clone())
)
Literal::new_typed_literal("foo", xsd::STRING)
);
assert_eq!(
Literal::new_simple_literal("foo"),
LiteralRef::new_typed_literal("foo", xsd::STRING)
);
assert_eq!(
LiteralRef::new_simple_literal("foo"),
Literal::new_typed_literal("foo", xsd::STRING)
);
assert_eq!(
LiteralRef::new_simple_literal("foo"),
LiteralRef::new_typed_literal("foo", xsd::STRING)
);
}
}

@ -9,9 +9,12 @@ mod triple;
pub mod vocab;
pub(crate) mod xsd;
pub use crate::model::blank_node::{BlankNode, BlankNodeIdParseError};
pub use crate::model::literal::Literal;
pub use crate::model::named_node::NamedNode;
pub use crate::model::triple::{GraphName, NamedOrBlankNode, Quad, Term, Triple};
pub use crate::model::blank_node::{BlankNode, BlankNodeIdParseError, BlankNodeRef};
pub use crate::model::literal::{Literal, LiteralRef};
pub use crate::model::named_node::{NamedNode, NamedNodeRef};
pub use crate::model::triple::{
GraphName, GraphNameRef, NamedOrBlankNode, NamedOrBlankNodeRef, Quad, QuadRef, Term, TermRef,
Triple, TripleRef,
};
pub use oxilangtag::LanguageTagParseError;
pub use oxiri::IriParseError;

@ -2,7 +2,7 @@ use oxiri::{Iri, IriParseError};
use rio_api::model as rio;
use std::fmt;
/// An RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri)
/// An owned RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri)
///
/// The default string formatter is returning a N-Triples, Turtle and SPARQL compatible representation:
/// ```
@ -50,17 +50,15 @@ impl NamedNode {
pub fn into_string(self) -> String {
self.iri
}
}
impl fmt::Display for NamedNode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
rio::NamedNode::from(self).fmt(f)
pub fn as_ref(&self) -> NamedNodeRef<'_> {
NamedNodeRef::new_unchecked(&self.iri)
}
}
impl<'a> From<&'a NamedNode> for rio::NamedNode<'a> {
fn from(node: &'a NamedNode) -> Self {
rio::NamedNode { iri: node.as_str() }
impl fmt::Display for NamedNode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.as_ref().fmt(f)
}
}
@ -87,3 +85,108 @@ impl PartialEq<NamedNode> for &str {
*self == other
}
}
/// A borrowed RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri)
///
/// The default string formatter is returning a N-Triples, Turtle and SPARQL compatible representation:
/// ```
/// use oxigraph::model::NamedNodeRef;
///
/// assert_eq!(
/// "<http://example.com/foo>",
/// NamedNodeRef::new("http://example.com/foo")?.to_string()
/// );
/// # Result::<_,oxigraph::model::IriParseError>::Ok(())
/// ```
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash)]
pub struct NamedNodeRef<'a> {
iri: &'a str,
}
impl<'a> NamedNodeRef<'a> {
/// Builds and validate an RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri)
pub fn new(iri: &'a str) -> Result<Self, IriParseError> {
Ok(Self::new_from_iri(Iri::parse(iri)?))
}
pub(crate) fn new_from_iri(iri: Iri<&'a str>) -> Self {
Self::new_unchecked(iri.into_inner())
}
/// Builds an RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) from a string.
///
/// It is the caller's responsibility to ensure that `iri` is a valid IRI.
///
/// Except if you really know what you do, you should use [`parse`](#method.parse).
pub const fn new_unchecked(iri: &'a str) -> Self {
Self { iri }
}
pub const fn as_str(self) -> &'a str {
self.iri
}
pub fn into_owned(self) -> NamedNode {
NamedNode::new_unchecked(self.iri)
}
}
impl fmt::Display for NamedNodeRef<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
rio::NamedNode::from(*self).fmt(f)
}
}
impl From<NamedNodeRef<'_>> for NamedNode {
fn from(node: NamedNodeRef<'_>) -> Self {
node.into_owned()
}
}
impl<'a> From<&'a NamedNode> for NamedNodeRef<'a> {
fn from(node: &'a NamedNode) -> Self {
node.as_ref()
}
}
impl<'a> From<NamedNodeRef<'a>> for rio::NamedNode<'a> {
fn from(node: NamedNodeRef<'a>) -> Self {
rio::NamedNode { iri: node.as_str() }
}
}
impl PartialEq<NamedNode> for NamedNodeRef<'_> {
fn eq(&self, other: &NamedNode) -> bool {
self.as_str() == other.as_str()
}
}
impl PartialEq<NamedNodeRef<'_>> for NamedNode {
fn eq(&self, other: &NamedNodeRef<'_>) -> bool {
self.as_str() == other.as_str()
}
}
impl PartialEq<str> for NamedNodeRef<'_> {
fn eq(&self, other: &str) -> bool {
self.as_str() == other
}
}
impl PartialEq<NamedNodeRef<'_>> for str {
fn eq(&self, other: &NamedNodeRef<'_>) -> bool {
self == other.as_str()
}
}
impl PartialEq<&str> for NamedNodeRef<'_> {
fn eq(&self, other: &&str) -> bool {
self == *other
}
}
impl PartialEq<NamedNodeRef<'_>> for &str {
fn eq(&self, other: &NamedNodeRef<'_>) -> bool {
*self == other
}
}

@ -1,10 +1,11 @@
use crate::model::blank_node::BlankNode;
use crate::model::literal::Literal;
use crate::model::named_node::NamedNode;
use crate::model::{BlankNodeRef, LiteralRef, NamedNodeRef};
use rio_api::model as rio;
use std::fmt;
/// 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 owned 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).
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum NamedOrBlankNode {
NamedNode(NamedNode),
@ -13,51 +14,136 @@ pub enum NamedOrBlankNode {
impl NamedOrBlankNode {
pub fn is_named_node(&self) -> bool {
match self {
NamedOrBlankNode::NamedNode(_) => true,
NamedOrBlankNode::BlankNode(_) => false,
}
self.as_ref().is_named_node()
}
pub fn is_blank_node(&self) -> bool {
self.as_ref().is_blank_node()
}
pub fn as_ref(&self) -> NamedOrBlankNodeRef<'_> {
match self {
NamedOrBlankNode::NamedNode(_) => false,
NamedOrBlankNode::BlankNode(_) => true,
Self::NamedNode(node) => NamedOrBlankNodeRef::NamedNode(node.as_ref()),
Self::BlankNode(node) => NamedOrBlankNodeRef::BlankNode(node.as_ref()),
}
}
}
impl fmt::Display for NamedOrBlankNode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
NamedOrBlankNode::NamedNode(node) => node.fmt(f),
NamedOrBlankNode::BlankNode(node) => node.fmt(f),
}
self.as_ref().fmt(f)
}
}
impl From<NamedNode> for NamedOrBlankNode {
fn from(node: NamedNode) -> Self {
NamedOrBlankNode::NamedNode(node)
Self::NamedNode(node)
}
}
impl From<NamedNodeRef<'_>> for NamedOrBlankNode {
fn from(node: NamedNodeRef<'_>) -> Self {
node.into_owned().into()
}
}
impl From<BlankNode> for NamedOrBlankNode {
fn from(node: BlankNode) -> Self {
NamedOrBlankNode::BlankNode(node)
Self::BlankNode(node)
}
}
impl From<BlankNodeRef<'_>> for NamedOrBlankNode {
fn from(node: BlankNodeRef<'_>) -> Self {
node.into_owned().into()
}
}
/// The borrowed 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).
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub enum NamedOrBlankNodeRef<'a> {
NamedNode(NamedNodeRef<'a>),
BlankNode(BlankNodeRef<'a>),
}
impl<'a> NamedOrBlankNodeRef<'a> {
pub fn is_named_node(&self) -> bool {
match self {
Self::NamedNode(_) => true,
Self::BlankNode(_) => false,
}
}
pub fn is_blank_node(&self) -> bool {
match self {
Self::NamedNode(_) => false,
Self::BlankNode(_) => true,
}
}
pub fn into_owned(self) -> NamedOrBlankNode {
match self {
Self::NamedNode(node) => NamedOrBlankNode::NamedNode(node.into_owned()),
Self::BlankNode(node) => NamedOrBlankNode::BlankNode(node.into_owned()),
}
}
}
impl<'a> From<&'a NamedOrBlankNode> for rio::NamedOrBlankNode<'a> {
impl fmt::Display for NamedOrBlankNodeRef<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt(f),
Self::BlankNode(node) => node.fmt(f),
}
}
}
impl<'a> From<NamedNodeRef<'a>> for NamedOrBlankNodeRef<'a> {
fn from(node: NamedNodeRef<'a>) -> Self {
Self::NamedNode(node)
}
}
impl<'a> From<&'a NamedNode> for NamedOrBlankNodeRef<'a> {
fn from(node: &'a NamedNode) -> Self {
node.as_ref().into()
}
}
impl<'a> From<BlankNodeRef<'a>> for NamedOrBlankNodeRef<'a> {
fn from(node: BlankNodeRef<'a>) -> Self {
Self::BlankNode(node)
}
}
impl<'a> From<&'a BlankNode> for NamedOrBlankNodeRef<'a> {
fn from(node: &'a BlankNode) -> Self {
node.as_ref().into()
}
}
impl<'a> From<&'a NamedOrBlankNode> for NamedOrBlankNodeRef<'a> {
fn from(node: &'a NamedOrBlankNode) -> Self {
node.as_ref()
}
}
impl<'a> From<NamedOrBlankNodeRef<'a>> for NamedOrBlankNode {
fn from(node: NamedOrBlankNodeRef<'a>) -> Self {
node.into_owned()
}
}
impl<'a> From<NamedOrBlankNodeRef<'a>> for rio::NamedOrBlankNode<'a> {
fn from(node: NamedOrBlankNodeRef<'a>) -> Self {
match node {
NamedOrBlankNode::NamedNode(node) => rio::NamedNode::from(node).into(),
NamedOrBlankNode::BlankNode(node) => rio::BlankNode::from(node).into(),
NamedOrBlankNodeRef::NamedNode(node) => rio::NamedNode::from(node).into(),
NamedOrBlankNodeRef::BlankNode(node) => rio::BlankNode::from(node).into(),
}
}
}
/// An RDF [term](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-term)
/// An owned RDF [term](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-term)
/// 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).
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum Term {
@ -68,75 +154,207 @@ pub enum Term {
impl Term {
pub fn is_named_node(&self) -> bool {
match self {
Term::NamedNode(_) => true,
_ => false,
}
self.as_ref().is_named_node()
}
pub fn is_blank_node(&self) -> bool {
match self {
Term::BlankNode(_) => true,
_ => false,
}
self.as_ref().is_blank_node()
}
pub fn is_literal(&self) -> bool {
self.as_ref().is_literal()
}
pub fn as_ref(&self) -> TermRef<'_> {
match self {
Term::Literal(_) => true,
_ => false,
Self::NamedNode(node) => TermRef::NamedNode(node.as_ref()),
Self::BlankNode(node) => TermRef::BlankNode(node.as_ref()),
Self::Literal(literal) => TermRef::Literal(literal.as_ref()),
}
}
}
impl fmt::Display for Term {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Term::NamedNode(node) => node.fmt(f),
Term::BlankNode(node) => node.fmt(f),
Term::Literal(literal) => literal.fmt(f),
}
self.as_ref().fmt(f)
}
}
impl From<NamedNode> for Term {
fn from(node: NamedNode) -> Self {
Term::NamedNode(node)
Self::NamedNode(node)
}
}
impl From<NamedNodeRef<'_>> for Term {
fn from(node: NamedNodeRef<'_>) -> Self {
node.into_owned().into()
}
}
impl From<BlankNode> for Term {
fn from(node: BlankNode) -> Self {
Term::BlankNode(node)
Self::BlankNode(node)
}
}
impl From<BlankNodeRef<'_>> for Term {
fn from(node: BlankNodeRef<'_>) -> Self {
node.into_owned().into()
}
}
impl From<Literal> for Term {
fn from(literal: Literal) -> Self {
Term::Literal(literal)
Self::Literal(literal)
}
}
impl From<LiteralRef<'_>> for Term {
fn from(literal: LiteralRef<'_>) -> Self {
literal.into_owned().into()
}
}
impl From<NamedOrBlankNode> for Term {
fn from(resource: NamedOrBlankNode) -> Self {
match resource {
fn from(node: NamedOrBlankNode) -> Self {
match node {
NamedOrBlankNode::NamedNode(node) => node.into(),
NamedOrBlankNode::BlankNode(node) => node.into(),
}
}
}
impl<'a> From<&'a Term> for rio::Term<'a> {
impl From<NamedOrBlankNodeRef<'_>> for Term {
fn from(node: NamedOrBlankNodeRef<'_>) -> Self {
node.into_owned().into()
}
}
/// A borrowed RDF [term](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-term)
/// 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).
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub enum TermRef<'a> {
NamedNode(NamedNodeRef<'a>),
BlankNode(BlankNodeRef<'a>),
Literal(LiteralRef<'a>),
}
impl<'a> TermRef<'a> {
pub fn is_named_node(&self) -> bool {
match self {
Self::NamedNode(_) => true,
_ => false,
}
}
pub fn is_blank_node(&self) -> bool {
match self {
Self::BlankNode(_) => true,
_ => false,
}
}
pub fn is_literal(&self) -> bool {
match self {
Self::Literal(_) => true,
_ => false,
}
}
pub fn into_owned(self) -> Term {
match self {
Self::NamedNode(node) => Term::NamedNode(node.into_owned()),
Self::BlankNode(node) => Term::BlankNode(node.into_owned()),
Self::Literal(literal) => Term::Literal(literal.into_owned()),
}
}
}
impl fmt::Display for TermRef<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt(f),
Self::BlankNode(node) => node.fmt(f),
Self::Literal(node) => node.fmt(f),
}
}
}
impl<'a> From<NamedNodeRef<'a>> for TermRef<'a> {
fn from(node: NamedNodeRef<'a>) -> Self {
Self::NamedNode(node)
}
}
impl<'a> From<&'a NamedNode> for TermRef<'a> {
fn from(node: &'a NamedNode) -> Self {
node.as_ref().into()
}
}
impl<'a> From<BlankNodeRef<'a>> for TermRef<'a> {
fn from(node: BlankNodeRef<'a>) -> Self {
Self::BlankNode(node)
}
}
impl<'a> From<&'a BlankNode> for TermRef<'a> {
fn from(node: &'a BlankNode) -> Self {
node.as_ref().into()
}
}
impl<'a> From<LiteralRef<'a>> for TermRef<'a> {
fn from(literal: LiteralRef<'a>) -> Self {
Self::Literal(literal)
}
}
impl<'a> From<&'a Literal> for TermRef<'a> {
fn from(literal: &'a Literal) -> Self {
literal.as_ref().into()
}
}
impl<'a> From<NamedOrBlankNodeRef<'a>> for TermRef<'a> {
fn from(node: NamedOrBlankNodeRef<'a>) -> Self {
match node {
NamedOrBlankNodeRef::NamedNode(node) => node.into(),
NamedOrBlankNodeRef::BlankNode(node) => node.into(),
}
}
}
impl<'a> From<&'a NamedOrBlankNode> for TermRef<'a> {
fn from(node: &'a NamedOrBlankNode) -> Self {
node.as_ref().into()
}
}
impl<'a> From<&'a Term> for TermRef<'a> {
fn from(node: &'a Term) -> Self {
node.as_ref()
}
}
impl<'a> From<TermRef<'a>> for Term {
fn from(node: TermRef<'a>) -> Self {
node.into_owned()
}
}
impl<'a> From<TermRef<'a>> for rio::Term<'a> {
fn from(node: TermRef<'a>) -> Self {
match node {
Term::NamedNode(node) => rio::NamedNode::from(node).into(),
Term::BlankNode(node) => rio::BlankNode::from(node).into(),
Term::Literal(node) => rio::Literal::from(node).into(),
TermRef::NamedNode(node) => rio::NamedNode::from(node).into(),
TermRef::BlankNode(node) => rio::BlankNode::from(node).into(),
TermRef::Literal(node) => rio::Literal::from(node).into(),
}
}
}
/// A [RDF triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple)
/// An owned [RDF triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple)
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct Triple {
/// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple
@ -202,25 +420,97 @@ impl Triple {
graph_name: graph_name.into(),
}
}
pub fn as_ref(&self) -> TripleRef<'_> {
TripleRef {
subject: self.subject.as_ref(),
predicate: self.predicate.as_ref(),
object: self.object.as_ref(),
}
}
}
impl fmt::Display for Triple {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
rio::Triple::from(self).fmt(f)
self.as_ref().fmt(f)
}
}
/// A borrowed [RDF triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple)
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub struct TripleRef<'a> {
/// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple
pub subject: NamedOrBlankNodeRef<'a>,
/// The [predicate](https://www.w3.org/TR/rdf11-concepts/#dfn-predicate) of this triple
pub predicate: NamedNodeRef<'a>,
/// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple
pub object: TermRef<'a>,
}
impl<'a> TripleRef<'a> {
/// Builds an RDF [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple)
pub fn new(
subject: impl Into<NamedOrBlankNodeRef<'a>>,
predicate: impl Into<NamedNodeRef<'a>>,
object: impl Into<TermRef<'a>>,
) -> Self {
Self {
subject: subject.into(),
predicate: predicate.into(),
object: object.into(),
}
}
/// Encodes that this triple is in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset)
pub fn in_graph(self, graph_name: impl Into<GraphNameRef<'a>>) -> QuadRef<'a> {
QuadRef {
subject: self.subject,
predicate: self.predicate,
object: self.object,
graph_name: graph_name.into(),
}
}
pub fn into_owned(self) -> Triple {
Triple {
subject: self.subject.into_owned(),
predicate: self.predicate.into_owned(),
object: self.object.into_owned(),
}
}
}
impl fmt::Display for TripleRef<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
rio::Triple::from(*self).fmt(f)
}
}
impl<'a> From<&'a Triple> for TripleRef<'a> {
fn from(triple: &'a Triple) -> Self {
triple.as_ref()
}
}
impl<'a> From<&'a Triple> for rio::Triple<'a> {
fn from(node: &'a Triple) -> Self {
impl<'a> From<TripleRef<'a>> for Triple {
fn from(triple: TripleRef<'a>) -> Self {
triple.into_owned()
}
}
impl<'a> From<TripleRef<'a>> for rio::Triple<'a> {
fn from(triple: TripleRef<'a>) -> Self {
rio::Triple {
subject: (&node.subject).into(),
predicate: (&node.predicate).into(),
object: (&node.object).into(),
subject: triple.subject.into(),
predicate: triple.predicate.into(),
object: triple.object.into(),
}
}
}
/// A possible graph name.
/// A possible owned graph name.
/// 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 the [default graph name](https://www.w3.org/TR/rdf11-concepts/#dfn-default-graph).
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum GraphName {
@ -231,34 +521,29 @@ pub enum GraphName {
impl GraphName {
pub fn is_named_node(&self) -> bool {
match self {
GraphName::NamedNode(_) => true,
_ => false,
}
self.as_ref().is_named_node()
}
pub fn is_blank_node(&self) -> bool {
match self {
GraphName::BlankNode(_) => true,
_ => false,
}
self.as_ref().is_blank_node()
}
pub fn is_default_graph(&self) -> bool {
self.as_ref().is_default_graph()
}
pub fn as_ref(&self) -> GraphNameRef<'_> {
match self {
GraphName::DefaultGraph => true,
_ => false,
Self::NamedNode(node) => GraphNameRef::NamedNode(node.as_ref()),
Self::BlankNode(node) => GraphNameRef::BlankNode(node.as_ref()),
Self::DefaultGraph => GraphNameRef::DefaultGraph,
}
}
}
impl fmt::Display for GraphName {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
GraphName::NamedNode(node) => node.fmt(f),
GraphName::BlankNode(node) => node.fmt(f),
GraphName::DefaultGraph => write!(f, "DEFAULT"),
}
self.as_ref().fmt(f)
}
}
@ -268,12 +553,24 @@ impl From<NamedNode> for GraphName {
}
}
impl From<NamedNodeRef<'_>> for GraphName {
fn from(node: NamedNodeRef<'_>) -> Self {
node.into_owned().into()
}
}
impl From<BlankNode> for GraphName {
fn from(node: BlankNode) -> Self {
GraphName::BlankNode(node)
}
}
impl From<BlankNodeRef<'_>> for GraphName {
fn from(node: BlankNodeRef<'_>) -> Self {
node.into_owned().into()
}
}
impl From<NamedOrBlankNode> for GraphName {
fn from(node: NamedOrBlankNode) -> Self {
match node {
@ -283,6 +580,12 @@ impl From<NamedOrBlankNode> for GraphName {
}
}
impl From<NamedOrBlankNodeRef<'_>> for GraphName {
fn from(node: NamedOrBlankNodeRef<'_>) -> Self {
node.into_owned().into()
}
}
impl From<Option<NamedOrBlankNode>> for GraphName {
fn from(name: Option<NamedOrBlankNode>) -> Self {
if let Some(node) = name {
@ -303,17 +606,138 @@ impl From<GraphName> for Option<NamedOrBlankNode> {
}
}
impl<'a> From<&'a GraphName> for Option<rio::NamedOrBlankNode<'a>> {
fn from(name: &'a GraphName) -> Self {
/// A possible borrowed graph name.
/// 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 the [default graph name](https://www.w3.org/TR/rdf11-concepts/#dfn-default-graph).
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub enum GraphNameRef<'a> {
NamedNode(NamedNodeRef<'a>),
BlankNode(BlankNodeRef<'a>),
DefaultGraph,
}
impl<'a> GraphNameRef<'a> {
pub fn is_named_node(&self) -> bool {
match self {
GraphNameRef::NamedNode(_) => true,
_ => false,
}
}
pub fn is_blank_node(&self) -> bool {
match self {
GraphNameRef::BlankNode(_) => true,
_ => false,
}
}
pub fn is_default_graph(&self) -> bool {
match self {
GraphNameRef::DefaultGraph => true,
_ => false,
}
}
pub fn into_owned(self) -> GraphName {
match self {
Self::NamedNode(node) => GraphName::NamedNode(node.into_owned()),
Self::BlankNode(node) => GraphName::BlankNode(node.into_owned()),
Self::DefaultGraph => GraphName::DefaultGraph,
}
}
}
impl fmt::Display for GraphNameRef<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt(f),
Self::BlankNode(node) => node.fmt(f),
Self::DefaultGraph => write!(f, "DEFAULT"),
}
}
}
impl<'a> From<NamedNodeRef<'a>> for GraphNameRef<'a> {
fn from(node: NamedNodeRef<'a>) -> Self {
Self::NamedNode(node)
}
}
impl<'a> From<&'a NamedNode> for GraphNameRef<'a> {
fn from(node: &'a NamedNode) -> Self {
node.as_ref().into()
}
}
impl<'a> From<BlankNodeRef<'a>> for GraphNameRef<'a> {
fn from(node: BlankNodeRef<'a>) -> Self {
Self::BlankNode(node)
}
}
impl<'a> From<&'a BlankNode> for GraphNameRef<'a> {
fn from(node: &'a BlankNode) -> Self {
node.as_ref().into()
}
}
impl<'a> From<NamedOrBlankNodeRef<'a>> for GraphNameRef<'a> {
fn from(node: NamedOrBlankNodeRef<'a>) -> Self {
match node {
NamedOrBlankNodeRef::NamedNode(node) => node.into(),
NamedOrBlankNodeRef::BlankNode(node) => node.into(),
}
}
}
impl<'a> From<&'a NamedOrBlankNode> for GraphNameRef<'a> {
fn from(node: &'a NamedOrBlankNode) -> Self {
node.as_ref().into()
}
}
impl<'a> From<&'a GraphName> for GraphNameRef<'a> {
fn from(node: &'a GraphName) -> Self {
node.as_ref()
}
}
impl<'a> From<GraphNameRef<'a>> for GraphName {
fn from(node: GraphNameRef<'a>) -> Self {
node.into_owned()
}
}
impl<'a> From<Option<NamedOrBlankNodeRef<'a>>> for GraphNameRef<'a> {
fn from(name: Option<NamedOrBlankNodeRef<'a>>) -> Self {
if let Some(node) = name {
node.into()
} else {
GraphNameRef::DefaultGraph
}
}
}
impl<'a> From<GraphNameRef<'a>> for Option<NamedOrBlankNodeRef<'a>> {
fn from(name: GraphNameRef<'a>) -> Self {
match name {
GraphName::NamedNode(node) => Some(rio::NamedNode::from(node).into()),
GraphName::BlankNode(node) => Some(rio::BlankNode::from(node).into()),
GraphName::DefaultGraph => None,
GraphNameRef::NamedNode(node) => Some(node.into()),
GraphNameRef::BlankNode(node) => Some(node.into()),
GraphNameRef::DefaultGraph => None,
}
}
}
impl<'a> From<GraphNameRef<'a>> for Option<rio::NamedOrBlankNode<'a>> {
fn from(name: GraphNameRef<'a>) -> Self {
match name {
GraphNameRef::NamedNode(node) => Some(rio::NamedNode::from(node).into()),
GraphNameRef::BlankNode(node) => Some(rio::BlankNode::from(node).into()),
GraphNameRef::DefaultGraph => None,
}
}
}
/// A [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset)
/// An owned [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset)
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct Quad {
/// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple
@ -394,27 +818,83 @@ impl Quad {
pub fn destruct(self) -> (NamedOrBlankNode, NamedNode, Term, GraphName) {
(self.subject, self.predicate, self.object, self.graph_name)
}
pub fn as_ref(&self) -> QuadRef<'_> {
QuadRef {
subject: self.subject.as_ref(),
predicate: self.predicate.as_ref(),
object: self.object.as_ref(),
graph_name: self.graph_name.as_ref(),
}
}
}
impl fmt::Display for Quad {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
rio::Quad::from(self).fmt(f)
self.as_ref().fmt(f)
}
}
impl<'a> From<&'a Quad> for rio::Quad<'a> {
fn from(node: &'a Quad) -> Self {
rio::Quad {
subject: (&node.subject).into(),
predicate: (&node.predicate).into(),
object: (&node.object).into(),
graph_name: (&node.graph_name).into(),
impl From<Quad> for Triple {
fn from(quad: Quad) -> Self {
Self {
subject: quad.subject,
predicate: quad.predicate,
object: quad.object,
}
}
}
impl From<Quad> for Triple {
fn from(quad: Quad) -> Self {
/// A borrowed [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset)
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub struct QuadRef<'a> {
/// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple
pub subject: NamedOrBlankNodeRef<'a>,
/// The [predicate](https://www.w3.org/TR/rdf11-concepts/#dfn-predicate) of this triple
pub predicate: NamedNodeRef<'a>,
/// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple
pub object: TermRef<'a>,
/// The name of the RDF [graph](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-graph) in which the triple is.
pub graph_name: GraphNameRef<'a>,
}
impl<'a> QuadRef<'a> {
/// Builds an RDF [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset)
pub fn new(
subject: impl Into<NamedOrBlankNodeRef<'a>>,
predicate: impl Into<NamedNodeRef<'a>>,
object: impl Into<TermRef<'a>>,
graph_name: impl Into<GraphNameRef<'a>>,
) -> Self {
Self {
subject: subject.into(),
predicate: predicate.into(),
object: object.into(),
graph_name: graph_name.into(),
}
}
pub fn into_owned(self) -> Quad {
Quad {
subject: self.subject.into_owned(),
predicate: self.predicate.into_owned(),
object: self.object.into_owned(),
graph_name: self.graph_name.into_owned(),
}
}
}
impl fmt::Display for QuadRef<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
rio::Quad::from(*self).fmt(f)
}
}
impl<'a> From<QuadRef<'a>> for TripleRef<'a> {
fn from(quad: QuadRef<'a>) -> Self {
Self {
subject: quad.subject,
predicate: quad.predicate,
@ -422,3 +902,26 @@ impl From<Quad> for Triple {
}
}
}
impl<'a> From<&'a Quad> for QuadRef<'a> {
fn from(quad: &'a Quad) -> Self {
quad.as_ref()
}
}
impl<'a> From<QuadRef<'a>> for Quad {
fn from(quad: QuadRef<'a>) -> Self {
quad.into_owned()
}
}
impl<'a> From<QuadRef<'a>> for rio::Quad<'a> {
fn from(quad: QuadRef<'a>) -> Self {
rio::Quad {
subject: quad.subject.into(),
predicate: quad.predicate.into(),
object: quad.object.into(),
graph_name: quad.graph_name.into(),
}
}
}

@ -2,212 +2,204 @@
pub mod rdf {
//! [RDF 1.1](https://www.w3.org/TR/rdf11-concepts/) vocabulary
use crate::model::named_node::NamedNode;
use lazy_static::lazy_static;
use crate::model::named_node::NamedNodeRef;
lazy_static! {
/// The class of containers of alternatives.
pub static ref ALT: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#Alt");
pub const ALT: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#Alt");
/// The class of unordered containers.
pub static ref BAG: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag");
pub const BAG: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag");
/// The first item in the subject RDF list.
pub static ref FIRST: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#first");
pub const FIRST: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#first");
/// The class of HTML literal values.
pub static ref HTML: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#HTML");
pub const HTML: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#HTML");
/// The class of language-tagged string literal values.
pub static ref LANG_STRING: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#langString");
pub const LANG_STRING: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#langString");
/// The class of RDF Lists.
pub static ref LIST: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#List");
pub static ref NIL: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil");
pub const LIST: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#List");
pub const NIL: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil");
/// The object of the subject RDF statement.
pub static ref OBJECT: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#object");
pub const OBJECT: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#object");
/// The predicate of the subject RDF statement.
pub static ref PREDICATE: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#predicate");
pub const PREDICATE: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#predicate");
/// The class of RDF properties.
pub static ref PROPERTY: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#Property");
pub const PROPERTY: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#Property");
/// The rest of the subject RDF list after the first item.
pub static ref REST: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest");
pub const REST: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest");
/// The class of ordered containers.
pub static ref SEQ: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#Seq");
pub const SEQ: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#Seq");
/// The class of RDF statements.
pub static ref STATEMENT: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#Statement");
pub const STATEMENT: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#Statement");
/// The subject of the subject RDF statement.
pub static ref SUBJECT: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#subject");
pub const SUBJECT: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#subject");
/// The subject is an instance of a class.
pub static ref TYPE: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
pub const TYPE: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
/// Idiomatic property used for structured values.
pub static ref VALUE: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#value");
pub const VALUE: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#value");
/// The class of XML literal values.
pub static ref XML_LITERAL: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral");
}
pub const XML_LITERAL: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral");
}
pub mod rdfs {
//! [RDFS](https://www.w3.org/TR/rdf-schema/) vocabulary
use crate::model::named_node::NamedNode;
use lazy_static::lazy_static;
use crate::model::named_node::NamedNodeRef;
lazy_static! {
/// The class of classes.
pub static ref CLASS: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#Class");
pub const CLASS: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2000/01/rdf-schema#Class");
/// A description of the subject resource.
pub static ref COMMENT: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#comment");
pub const COMMENT: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2000/01/rdf-schema#comment");
/// The class of RDF containers.
pub static ref CONTAINER: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#Container");
pub const CONTAINER: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2000/01/rdf-schema#Container");
/// The class of container membership properties, rdf:_1, rdf:_2, ..., all of which are sub-properties of 'member'.
pub static ref CONTAINER_MEMBERSHIP_PROPERTY: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#ContainerMembershipProperty");
pub const CONTAINER_MEMBERSHIP_PROPERTY: NamedNodeRef<'_> = NamedNodeRef::new_unchecked(
"http://www.w3.org/2000/01/rdf-schema#ContainerMembershipProperty",
);
/// The class of RDF datatypes.
pub static ref DATATYPE: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#Datatype");
pub const DATATYPE: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2000/01/rdf-schema#Datatype");
/// A domain of the subject property.
pub static ref DOMAIN: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#domain");
pub const DOMAIN: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2000/01/rdf-schema#domain");
/// The definition of the subject resource.
pub static ref IS_DEFINED_BY: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#isDefinedBy");
pub const IS_DEFINED_BY: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2000/01/rdf-schema#isDefinedBy");
/// A human-readable name for the subject.
pub static ref LABEL: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#label");
pub const LABEL: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2000/01/rdf-schema#label");
/// The class of literal values, e.g. textual strings and integers.
pub static ref LITERAL: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#Literal");
pub const LITERAL: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2000/01/rdf-schema#Literal");
/// A member of the subject resource.
pub static ref MEMBER: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#member");
pub const MEMBER: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2000/01/rdf-schema#member");
/// A range of the subject property.
pub static ref RANGE: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#range");
pub const RANGE: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2000/01/rdf-schema#range");
/// The class resource, everything.
pub static ref RESOURCE: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#Resource");
pub const RESOURCE: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2000/01/rdf-schema#Resource");
/// Further information about the subject resource.
pub static ref SEE_ALSO: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#seeAlso");
pub const SEE_ALSO: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2000/01/rdf-schema#seeAlso");
/// The subject is a subclass of a class.
pub static ref SUB_CLASS_OF: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#subClassOf");
pub const SUB_CLASS_OF: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2000/01/rdf-schema#subClassOf");
/// The subject is a subproperty of a property.
pub static ref SUB_PROPERTY_OF: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#subPropertyOf");
}
pub const SUB_PROPERTY_OF: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2000/01/rdf-schema#subPropertyOf");
}
pub mod xsd {
//! `NamedNode`s for [RDF compatible XSD datatypes](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-compatible-xsd-types)
use crate::model::named_node::NamedNode;
use lazy_static::lazy_static;
use crate::model::named_node::NamedNodeRef;
lazy_static! {
/// true, false
pub static ref BOOLEAN: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#boolean");
pub const BOOLEAN: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#boolean");
/// 128…+127 (8 bit)
pub static ref BYTE: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#byte");
pub const BYTE: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#byte");
/// Dates (yyyy-mm-dd) with or without timezone
pub static ref DATE: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#date");
pub const DATE: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#date");
/// Duration of time (days, hours, minutes, seconds only)
pub static ref DAY_TIME_DURATION: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#dayTimeDuration");
pub const DAY_TIME_DURATION: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#dayTimeDuration");
/// Date and time with or without timezone
pub static ref DATE_TIME: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#dateTime");
pub const DATE_TIME: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#dateTime");
/// Date and time with required timezone
pub static ref DATE_TIME_STAMP: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#dateTimeStamp");
pub const DATE_TIME_STAMP: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#dateTimeStamp");
/// Arbitrary-precision decimal numbers
pub static ref DECIMAL: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#decimal");
pub const DECIMAL: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#decimal");
/// 64-bit floating point numbers incl. ±Inf, ±0, NaN
pub static ref DOUBLE: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#double");
pub const DOUBLE: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#double");
/// Duration of time
pub static ref DURATION: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#duration");
pub const DURATION: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#duration");
/// 32-bit floating point numbers incl. ±Inf, ±0, NaN
pub static ref FLOAT: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#float");
pub const FLOAT: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#float");
/// Gregorian calendar day of the month
pub static ref G_DAY: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#gDay");
pub const G_DAY: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#gDay");
/// Gregorian calendar month
pub static ref G_MONTH: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#gMonth");
pub const G_MONTH: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#gMonth");
/// Gregorian calendar month and day
pub static ref G_MONTH_DAY: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#gMonthDay");
pub const G_MONTH_DAY: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#gMonthDay");
/// Gregorian calendar year
pub static ref G_YEAR: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#gYear");
pub const G_YEAR: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#gYear");
/// Gregorian calendar year and month
pub static ref G_YEAR_MONTH: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#gYearMonth");
pub const G_YEAR_MONTH: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#gYearMonth");
/// -2147483648…+2147483647 (32 bit)
pub static ref INT: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#int");
pub const INT: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#int");
/// Arbitrary-size integer numbers
pub static ref INTEGER: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#integer");
pub const INTEGER: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#integer");
/// -9223372036854775808…+9223372036854775807 (64 bit)
pub static ref LONG: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#long");
pub const LONG: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#long");
/// Integer numbers <0
pub static ref NEGATIVE_INTEGER: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#negativeInteger");
pub const NEGATIVE_INTEGER: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#negativeInteger");
/// Integer numbers ≥0
pub static ref NON_NEGATIVE_INTEGER: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#nonNegativeInteger");
pub const NON_NEGATIVE_INTEGER: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#nonNegativeInteger");
/// Integer numbers ≤0
pub static ref NON_POSITIVE_INTEGER: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#nonPositiveInteger");
pub const NON_POSITIVE_INTEGER: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#nonPositiveInteger");
/// Integer numbers >0
pub static ref POSITIVE_INTEGER: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#positiveInteger");
pub const POSITIVE_INTEGER: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#positiveInteger");
/// Times (hh:mm:ss.sss…) with or without timezone
pub static ref TIME: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#time");
pub const TIME: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#time");
/// -32768…+32767 (16 bit)
pub static ref SHORT: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#short");
pub const SHORT: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#short");
/// Character strings (but not all Unicode character strings)
pub static ref STRING: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#string");
pub const STRING: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#string");
/// 0…255 (8 bit)
pub static ref UNSIGNED_BYTE: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#unsignedByte");
pub const UNSIGNED_BYTE: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#unsignedByte");
/// 0…4294967295 (32 bit)
pub static ref UNSIGNED_INT: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#unsignedInt");
pub const UNSIGNED_INT: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#unsignedInt");
/// 0…18446744073709551615 (64 bit)
pub static ref UNSIGNED_LONG: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#unsignedLong");
pub const UNSIGNED_LONG: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#unsignedLong");
/// 0…65535 (16 bit)
pub static ref UNSIGNED_SHORT: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#unsignedShort");
pub const UNSIGNED_SHORT: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#unsignedShort");
/// Duration of time (months and years only)
pub static ref YEAR_MONTH_DURATION: NamedNode =
NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#yearMonthDuration");
}
pub const YEAR_MONTH_DURATION: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/XMLSchema#yearMonthDuration");
}

@ -30,6 +30,12 @@ impl From<NamedNode> for NamedNodeOrVariable {
}
}
impl From<NamedNodeRef<'_>> for NamedNodeOrVariable {
fn from(node: NamedNodeRef<'_>) -> Self {
NamedNodeOrVariable::NamedNode(node.into())
}
}
impl From<Variable> for NamedNodeOrVariable {
fn from(var: Variable) -> Self {
NamedNodeOrVariable::Variable(var)
@ -57,6 +63,12 @@ impl From<NamedNode> for TermOrVariable {
}
}
impl From<NamedNodeRef<'_>> for TermOrVariable {
fn from(node: NamedNodeRef<'_>) -> Self {
TermOrVariable::Term(node.into())
}
}
impl From<BlankNode> for TermOrVariable {
fn from(node: BlankNode) -> Self {
TermOrVariable::Term(node.into())

@ -1065,7 +1065,12 @@ where
let bnode =
BlankNode::new(self.to_simple_string(self.eval_expression(id, tuple)?)?)
.ok()?;
Some(self.dataset.as_ref().encode_blank_node(&bnode).ok()?)
Some(
self.dataset
.as_ref()
.encode_blank_node(bnode.as_ref())
.ok()?,
)
}
None => Some(EncodedTerm::InlineBlankNode {
id: random::<u128>(),
@ -1741,7 +1746,7 @@ where
put_variable_value(
variable,
&variables,
encoder.encode_term(term).map_err(|e| e.into())?,
encoder.encode_term(term.as_ref()).map_err(|e| e.into())?,
&mut encoded_terms,
)
}

@ -1052,7 +1052,7 @@ parser! {
}
//[78]
rule Verb() -> NamedNodeOrVariable = VarOrIri() / "a" { rdf::TYPE.clone().into() }
rule Verb() -> NamedNodeOrVariable = VarOrIri() / "a" { rdf::TYPE.into() }
//[79]
rule ObjectList() -> FocusedTriplePattern<Vec<TermOrVariable>> = o:ObjectList_item() **<1,> ("," _) {
@ -1172,7 +1172,7 @@ parser! {
//[94]
rule PathPrimary() -> PropertyPath =
v:iri() { v.into() } /
"a" { rdf::TYPE.clone().into() } /
"a" { NamedNode::from(rdf::TYPE).into() } /
"!" _ p:PathNegatedPropertySet() { p } /
"(" _ p:Path() _ ")" { p }
@ -1209,9 +1209,9 @@ parser! {
//[96]
rule PathOneInPropertySet() -> Either<NamedNode,NamedNode> =
"^" _ v:iri() { Either::Right(v) } /
"^" _ "a" { Either::Right(rdf::TYPE.clone()) } /
"^" _ "a" { Either::Right(rdf::TYPE.into()) } /
v:iri() { Either::Left(v) } /
"a" { Either::Left(rdf::TYPE.clone()) }
"a" { Either::Left(rdf::TYPE.into()) }
//[98]
rule TriplesNode() -> FocusedTriplePattern<TermOrVariable> = Collection() / BlankNodePropertyList()
@ -1252,11 +1252,11 @@ parser! {
//[102]
rule Collection() -> FocusedTriplePattern<TermOrVariable> = "(" _ o:Collection_item()+ ")" {
let mut patterns: Vec<TriplePattern> = Vec::default();
let mut current_list_node = TermOrVariable::from(rdf::NIL.clone());
let mut current_list_node = TermOrVariable::from(rdf::NIL);
for objWithPatterns in o.into_iter().rev() {
let new_blank_node = TermOrVariable::from(BlankNode::default());
patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::FIRST.clone(), objWithPatterns.focus.clone()));
patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::REST.clone(), current_list_node));
patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::FIRST, objWithPatterns.focus.clone()));
patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::REST, current_list_node));
current_list_node = new_blank_node;
patterns.extend_from_slice(&objWithPatterns.patterns);
}
@ -1270,11 +1270,11 @@ parser! {
//[103]
rule CollectionPath() -> FocusedTripleOrPathPattern<TermOrVariable> = "(" _ o:CollectionPath_item()+ _ ")" {
let mut patterns: Vec<TripleOrPathPattern> = Vec::default();
let mut current_list_node = TermOrVariable::from(rdf::NIL.clone());
let mut current_list_node = TermOrVariable::from(rdf::NIL);
for objWithPatterns in o.into_iter().rev() {
let new_blank_node = TermOrVariable::from(BlankNode::default());
patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::FIRST.clone(), objWithPatterns.focus.clone()).into());
patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::REST.clone(), current_list_node).into());
patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::FIRST, objWithPatterns.focus.clone()).into());
patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::REST, current_list_node).into());
current_list_node = new_blank_node;
patterns.extend_from_slice(&objWithPatterns.patterns);
}
@ -1315,7 +1315,7 @@ parser! {
l:NumericLiteral() { l.into() } /
l:BooleanLiteral() { l.into() } /
b:BlankNode() { b.into() } /
NIL() { rdf::NIL.clone().into() }
NIL() { rdf::NIL.into() }
//[110]
rule Expression() -> Expression = e:ConditionalOrExpression() {e}
@ -1523,8 +1523,8 @@ parser! {
Ok(value) => Ok(value.into()),
Err(_) => Err("Invalid xsd:double()")
} } /
d:$(DECIMAL()) { Literal::new_typed_literal(d, xsd::DECIMAL.clone()) } /
i:$(INTEGER()) { Literal::new_typed_literal(i, xsd::INTEGER.clone()) }
d:$(DECIMAL()) { Literal::new_typed_literal(d, xsd::DECIMAL) } /
i:$(INTEGER()) { Literal::new_typed_literal(i, xsd::INTEGER) }
//[132]
rule NumericLiteralPositive() -> Literal =
@ -1532,8 +1532,8 @@ parser! {
Ok(value) => Ok(value.into()),
Err(_) => Err("Invalid xsd:double()")
} } /
d:$(DECIMAL_POSITIVE()) { Literal::new_typed_literal(d, xsd::DECIMAL.clone()) } /
i:$(INTEGER_POSITIVE()) { Literal::new_typed_literal(i, xsd::INTEGER.clone()) }
d:$(DECIMAL_POSITIVE()) { Literal::new_typed_literal(d, xsd::DECIMAL) } /
i:$(INTEGER_POSITIVE()) { Literal::new_typed_literal(i, xsd::INTEGER) }
//[133]
@ -1542,8 +1542,8 @@ parser! {
Ok(value) => Ok(value.into()),
Err(_) => Err("Invalid xsd:double()")
} } /
d:$(DECIMAL_NEGATIVE()) { Literal::new_typed_literal(d, xsd::DECIMAL.clone()) } /
i:$(INTEGER_NEGATIVE()) { Literal::new_typed_literal(i, xsd::INTEGER.clone()) }
d:$(DECIMAL_NEGATIVE()) { Literal::new_typed_literal(d, xsd::DECIMAL) } /
i:$(INTEGER_NEGATIVE()) { Literal::new_typed_literal(i, xsd::INTEGER) }
//[134]
rule BooleanLiteral() -> Literal =

@ -992,17 +992,20 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
fn build_named_node(
&mut self,
term: &NamedNode,
node: &NamedNode,
) -> Result<EncodedTerm<E::StrId>, EvaluationError> {
Ok(self.encoder.encode_named_node(term)?)
Ok(self.encoder.encode_named_node(node.as_ref())?)
}
fn build_literal(&mut self, term: &Literal) -> Result<EncodedTerm<E::StrId>, EvaluationError> {
Ok(self.encoder.encode_literal(term)?)
fn build_literal(
&mut self,
literal: &Literal,
) -> Result<EncodedTerm<E::StrId>, EvaluationError> {
Ok(self.encoder.encode_literal(literal.as_ref())?)
}
fn build_term(&mut self, term: &Term) -> Result<EncodedTerm<E::StrId>, EvaluationError> {
Ok(self.encoder.encode_term(term)?)
Ok(self.encoder.encode_term(term.as_ref())?)
}
}

@ -40,7 +40,7 @@ use std::{fmt, io};
/// store.insert(quad.clone());
///
/// // quad filter
/// let results: Vec<Quad> = store.quads_for_pattern(Some(&ex.clone().into()), None, None, None).collect();
/// let results: Vec<Quad> = store.quads_for_pattern(Some(ex.as_ref().into()), None, None, None).collect();
/// assert_eq!(vec![quad], results);
///
/// // SPARQL query
@ -168,10 +168,10 @@ impl MemoryStore {
/// ```
pub fn quads_for_pattern(
&self,
subject: Option<&NamedOrBlankNode>,
predicate: Option<&NamedNode>,
object: Option<&Term>,
graph_name: Option<&GraphName>,
subject: Option<NamedOrBlankNodeRef<'_>>,
predicate: Option<NamedNodeRef<'_>>,
object: Option<TermRef<'_>>,
graph_name: Option<GraphNameRef<'_>>,
) -> impl Iterator<Item = Quad> {
let quads = if let Some((subject, predicate, object, graph_name)) =
get_encoded_quad_pattern(self, subject, predicate, object, graph_name)
@ -188,8 +188,8 @@ impl MemoryStore {
}
/// Checks if this store contains a given quad
pub fn contains(&self, quad: &Quad) -> bool {
self.get_encoded_quad(quad)
pub fn contains<'a>(&self, quad: impl Into<QuadRef<'a>>) -> bool {
self.get_encoded_quad(quad.into())
.unwrap_infallible()
.map_or(false, |q| self.contains_encoded(&q))
}
@ -250,11 +250,11 @@ impl MemoryStore {
for op in transaction.ops {
match op {
TransactionOp::Insert(quad) => {
let quad = this.encode_quad(&quad).unwrap_infallible();
let quad = this.encode_quad(quad.as_ref()).unwrap_infallible();
indexes.insert_encoded(&quad).unwrap_infallible()
}
TransactionOp::Delete(quad) => {
let quad = this.encode_quad(&quad).unwrap_infallible();
let quad = this.encode_quad(quad.as_ref()).unwrap_infallible();
indexes.remove_encoded(&quad).unwrap_infallible()
}
}
@ -285,15 +285,15 @@ impl MemoryStore {
///
/// Errors related to parameter validation like the base IRI use the `INVALID_INPUT` error kind.
/// Errors related to a bad syntax in the loaded file use the `INVALID_DATA` error kind.
pub fn load_graph(
pub fn load_graph<'a>(
&self,
reader: impl BufRead,
format: GraphFormat,
to_graph_name: &GraphName,
to_graph_name: impl Into<GraphNameRef<'a>>,
base_iri: Option<&str>,
) -> Result<(), io::Error> {
let mut store = self;
load_graph(&mut store, reader, format, to_graph_name, base_iri)?;
load_graph(&mut store, reader, format, to_graph_name.into(), base_iri)?;
Ok(())
}
@ -335,13 +335,13 @@ impl MemoryStore {
#[allow(clippy::needless_pass_by_value)]
pub fn insert(&self, quad: Quad) {
let mut this = self;
let quad = this.encode_quad(&quad).unwrap_infallible();
let quad = this.encode_quad(quad.as_ref()).unwrap_infallible();
this.insert_encoded(&quad).unwrap_infallible();
}
/// Removes a quad from this store.
pub fn remove(&self, quad: &Quad) {
if let Some(quad) = self.get_encoded_quad(quad).unwrap_infallible() {
pub fn remove<'a>(&self, quad: impl Into<QuadRef<'a>>) {
if let Some(quad) = self.get_encoded_quad(quad.into()).unwrap_infallible() {
let mut this = self;
this.remove_encoded(&quad).unwrap_infallible();
}
@ -378,14 +378,14 @@ impl MemoryStore {
///
/// Errors related to parameter validation like the base IRI use the `INVALID_INPUT` error kind.
/// Errors related to a bad syntax in the loaded file use the `INVALID_DATA` error kind.
pub fn dump_graph(
pub fn dump_graph<'a>(
&self,
writer: impl Write,
format: GraphFormat,
from_graph_name: &GraphName,
from_graph_name: impl Into<GraphNameRef<'a>>,
) -> Result<(), io::Error> {
dump_graph(
self.quads_for_pattern(None, None, None, Some(from_graph_name))
self.quads_for_pattern(None, None, None, Some(from_graph_name.into()))
.map(|q| Ok(q.into())),
writer,
format,
@ -973,13 +973,14 @@ impl MemoryTransaction {
/// assert_eq!(vec![Quad::new(ex.clone(), ex.clone(), ex.clone(), None)], results);
/// # Result::<_, oxigraph::sparql::EvaluationError>::Ok(())
/// ```
pub fn load_graph(
pub fn load_graph<'a>(
&mut self,
reader: impl BufRead,
format: GraphFormat,
to_graph_name: &GraphName,
to_graph_name: impl Into<GraphNameRef<'a>>,
base_iri: Option<&str>,
) -> Result<(), io::Error> {
let to_graph_name = to_graph_name.into();
let mut parser = GraphParser::from_format(format);
if let Some(base_iri) = base_iri {
parser = parser
@ -987,9 +988,8 @@ impl MemoryTransaction {
.map_err(invalid_input_error)?;
}
for triple in parser.read_triples(reader)? {
self.ops.push(TransactionOp::Insert(
triple?.in_graph(to_graph_name.clone()),
));
self.ops
.push(TransactionOp::Insert(triple?.in_graph(to_graph_name)));
}
Ok(())
}

@ -17,16 +17,12 @@ pub use crate::store::rocksdb::RocksDbStore;
pub use crate::store::sled::SledStore;
use crate::error::{invalid_data_error, invalid_input_error};
use crate::io::{DatasetFormat, GraphFormat};
use crate::io::{DatasetFormat, DatasetSerializer, GraphFormat, GraphSerializer};
use crate::model::*;
use crate::store::numeric_encoder::*;
use rio_api::formatter::{QuadsFormatter, TriplesFormatter};
use rio_api::parser::{QuadsParser, TriplesParser};
use rio_turtle::{
NQuadsFormatter, NQuadsParser, NTriplesFormatter, NTriplesParser, TriGFormatter, TriGParser,
TurtleError, TurtleFormatter, TurtleParser,
};
use rio_xml::{RdfXmlError, RdfXmlFormatter, RdfXmlParser};
use rio_turtle::{NQuadsParser, NTriplesParser, TriGParser, TurtleError, TurtleParser};
use rio_xml::{RdfXmlError, RdfXmlParser};
use std::collections::HashMap;
use std::convert::Infallible;
use std::io;
@ -55,7 +51,7 @@ fn load_graph<S: WritableEncodedStore + StrContainer>(
store: &mut S,
reader: impl BufRead,
format: GraphFormat,
to_graph_name: &GraphName,
to_graph_name: GraphNameRef<'_>,
base_iri: Option<&str>,
) -> Result<(), StoreOrParseError<S::Error, io::Error>> {
let base_iri = base_iri.unwrap_or("");
@ -75,7 +71,7 @@ fn load_graph<S: WritableEncodedStore + StrContainer>(
fn load_from_triple_parser<S: WritableEncodedStore + StrContainer, P: TriplesParser>(
store: &mut S,
parser: Result<P, P::Error>,
to_graph_name: &GraphName,
to_graph_name: GraphNameRef<'_>,
) -> Result<(), StoreOrParseError<S::Error, io::Error>>
where
StoreOrParseError<S::Error, P::Error>: From<P::Error>,
@ -107,34 +103,11 @@ fn dump_graph(
writer: impl Write,
format: GraphFormat,
) -> Result<(), io::Error> {
match format {
GraphFormat::NTriples => {
let mut formatter = NTriplesFormatter::new(writer);
for triple in triples {
formatter.format(&(&triple?).into())?;
}
formatter.finish();
}
GraphFormat::Turtle => {
let mut formatter = TurtleFormatter::new(writer);
let mut writer = GraphSerializer::from_format(format).triple_writer(writer)?;
for triple in triples {
formatter.format(&(&triple?).into())?;
}
formatter.finish()?;
}
GraphFormat::RdfXml => {
let mut formatter = RdfXmlFormatter::new(writer).map_err(map_xml_err)?;
for triple in triples {
formatter.format(&(&triple?).into()).map_err(map_xml_err)?;
}
formatter.finish().map_err(map_xml_err)?;
writer.write(&triple?)?;
}
}
Ok(())
}
fn map_xml_err(e: RdfXmlError) -> io::Error {
io::Error::new(io::ErrorKind::Other, e) // TODO: drop
writer.finish()
}
fn load_dataset<S: WritableEncodedStore + StrContainer>(
@ -181,23 +154,11 @@ fn dump_dataset(
writer: impl Write,
format: DatasetFormat,
) -> Result<(), io::Error> {
match format {
DatasetFormat::NQuads => {
let mut formatter = NQuadsFormatter::new(writer);
let mut writer = DatasetSerializer::from_format(format).quad_writer(writer)?;
for quad in quads {
formatter.format(&(&quad?).into())?;
}
formatter.finish();
writer.write(&quad?)?;
}
DatasetFormat::TriG => {
let mut formatter = TriGFormatter::new(writer);
for quad in quads {
formatter.format(&(&quad?).into())?;
}
formatter.finish()?;
}
}
Ok(())
writer.finish()
}
enum StoreOrParseError<S, P> {
@ -249,10 +210,10 @@ type QuadPattern<I> = (
fn get_encoded_quad_pattern<E: ReadEncoder>(
encoder: &E,
subject: Option<&NamedOrBlankNode>,
predicate: Option<&NamedNode>,
object: Option<&Term>,
graph_name: Option<&GraphName>,
subject: Option<NamedOrBlankNodeRef<'_>>,
predicate: Option<NamedNodeRef<'_>>,
object: Option<TermRef<'_>>,
graph_name: Option<GraphNameRef<'_>>,
) -> Result<Option<QuadPattern<E::StrId>>, E::Error> {
Ok(Some((
if let Some(subject) = transpose(

@ -787,7 +787,7 @@ impl StrContainer for MemoryStrStore {
pub(crate) trait ReadEncoder: WithStoreError {
fn get_encoded_named_node(
&self,
named_node: &NamedNode,
named_node: NamedNodeRef<'_>,
) -> Result<Option<EncodedTerm<Self::StrId>>, Self::Error> {
Ok(Some(EncodedTerm::NamedNode {
iri_id: if let Some(iri_id) = self.get_encoded_str(named_node.as_str())? {
@ -800,7 +800,7 @@ pub(crate) trait ReadEncoder: WithStoreError {
fn get_encoded_blank_node(
&self,
blank_node: &BlankNode,
blank_node: BlankNodeRef<'_>,
) -> Result<Option<EncodedTerm<Self::StrId>>, Self::Error> {
Ok(Some(if let Some(id) = blank_node.id() {
EncodedTerm::InlineBlankNode { id }
@ -817,7 +817,7 @@ pub(crate) trait ReadEncoder: WithStoreError {
fn get_encoded_literal(
&self,
literal: &Literal,
literal: LiteralRef<'_>,
) -> Result<Option<EncodedTerm<Self::StrId>>, Self::Error> {
Ok(Some(
match match literal.datatype().as_str() {
@ -905,57 +905,57 @@ pub(crate) trait ReadEncoder: WithStoreError {
fn get_encoded_named_or_blank_node(
&self,
term: &NamedOrBlankNode,
term: NamedOrBlankNodeRef<'_>,
) -> Result<Option<EncodedTerm<Self::StrId>>, Self::Error> {
match term {
NamedOrBlankNode::NamedNode(named_node) => self.get_encoded_named_node(named_node),
NamedOrBlankNode::BlankNode(blank_node) => self.get_encoded_blank_node(blank_node),
NamedOrBlankNodeRef::NamedNode(named_node) => self.get_encoded_named_node(named_node),
NamedOrBlankNodeRef::BlankNode(blank_node) => self.get_encoded_blank_node(blank_node),
}
}
fn get_encoded_term(
&self,
term: &Term,
term: TermRef<'_>,
) -> Result<Option<EncodedTerm<Self::StrId>>, Self::Error> {
match term {
Term::NamedNode(named_node) => self.get_encoded_named_node(named_node),
Term::BlankNode(blank_node) => self.get_encoded_blank_node(blank_node),
Term::Literal(literal) => self.get_encoded_literal(literal),
TermRef::NamedNode(named_node) => self.get_encoded_named_node(named_node),
TermRef::BlankNode(blank_node) => self.get_encoded_blank_node(blank_node),
TermRef::Literal(literal) => self.get_encoded_literal(literal),
}
}
fn get_encoded_graph_name(
&self,
name: &GraphName,
name: GraphNameRef<'_>,
) -> Result<Option<EncodedTerm<Self::StrId>>, Self::Error> {
match name {
GraphName::NamedNode(named_node) => self.get_encoded_named_node(named_node),
GraphName::BlankNode(blank_node) => self.get_encoded_blank_node(blank_node),
GraphName::DefaultGraph => Ok(Some(EncodedTerm::DefaultGraph)),
GraphNameRef::NamedNode(named_node) => self.get_encoded_named_node(named_node),
GraphNameRef::BlankNode(blank_node) => self.get_encoded_blank_node(blank_node),
GraphNameRef::DefaultGraph => Ok(Some(EncodedTerm::DefaultGraph)),
}
}
fn get_encoded_quad(
&self,
quad: &Quad,
quad: QuadRef<'_>,
) -> Result<Option<EncodedQuad<Self::StrId>>, Self::Error> {
Ok(Some(EncodedQuad {
subject: if let Some(subject) = self.get_encoded_named_or_blank_node(&quad.subject)? {
subject: if let Some(subject) = self.get_encoded_named_or_blank_node(quad.subject)? {
subject
} else {
return Ok(None);
},
predicate: if let Some(predicate) = self.get_encoded_named_node(&quad.predicate)? {
predicate: if let Some(predicate) = self.get_encoded_named_node(quad.predicate)? {
predicate
} else {
return Ok(None);
},
object: if let Some(object) = self.get_encoded_term(&quad.object)? {
object: if let Some(object) = self.get_encoded_term(quad.object)? {
object
} else {
return Ok(None);
},
graph_name: if let Some(graph_name) = self.get_encoded_graph_name(&quad.graph_name)? {
graph_name: if let Some(graph_name) = self.get_encoded_graph_name(quad.graph_name)? {
graph_name
} else {
return Ok(None);
@ -976,14 +976,14 @@ impl<S: StrLookup> ReadEncoder for S {
pub(crate) trait WriteEncoder: WithStoreError {
fn encode_named_node(
&mut self,
named_node: &NamedNode,
named_node: NamedNodeRef<'_>,
) -> Result<EncodedTerm<Self::StrId>, Self::Error> {
self.encode_rio_named_node(named_node.into())
}
fn encode_blank_node(
&mut self,
blank_node: &BlankNode,
blank_node: BlankNodeRef<'_>,
) -> Result<EncodedTerm<Self::StrId>, Self::Error> {
if let Some(id) = blank_node.id() {
Ok(EncodedTerm::InlineBlankNode { id })
@ -996,58 +996,58 @@ pub(crate) trait WriteEncoder: WithStoreError {
fn encode_literal(
&mut self,
literal: &Literal,
literal: LiteralRef<'_>,
) -> Result<EncodedTerm<Self::StrId>, Self::Error> {
self.encode_rio_literal(literal.into())
}
fn encode_named_or_blank_node(
&mut self,
term: &NamedOrBlankNode,
term: NamedOrBlankNodeRef<'_>,
) -> Result<EncodedTerm<Self::StrId>, Self::Error> {
match term {
NamedOrBlankNode::NamedNode(named_node) => self.encode_named_node(named_node),
NamedOrBlankNode::BlankNode(blank_node) => self.encode_blank_node(blank_node),
NamedOrBlankNodeRef::NamedNode(named_node) => self.encode_named_node(named_node),
NamedOrBlankNodeRef::BlankNode(blank_node) => self.encode_blank_node(blank_node),
}
}
fn encode_term(&mut self, term: &Term) -> Result<EncodedTerm<Self::StrId>, Self::Error> {
fn encode_term(&mut self, term: TermRef<'_>) -> Result<EncodedTerm<Self::StrId>, Self::Error> {
match term {
Term::NamedNode(named_node) => self.encode_named_node(named_node),
Term::BlankNode(blank_node) => self.encode_blank_node(blank_node),
Term::Literal(literal) => self.encode_literal(literal),
TermRef::NamedNode(named_node) => self.encode_named_node(named_node),
TermRef::BlankNode(blank_node) => self.encode_blank_node(blank_node),
TermRef::Literal(literal) => self.encode_literal(literal),
}
}
fn encode_graph_name(
&mut self,
name: &GraphName,
name: GraphNameRef<'_>,
) -> Result<EncodedTerm<Self::StrId>, Self::Error> {
match name {
GraphName::NamedNode(named_node) => self.encode_named_node(named_node),
GraphName::BlankNode(blank_node) => self.encode_blank_node(blank_node),
GraphName::DefaultGraph => Ok(EncodedTerm::DefaultGraph),
GraphNameRef::NamedNode(named_node) => self.encode_named_node(named_node),
GraphNameRef::BlankNode(blank_node) => self.encode_blank_node(blank_node),
GraphNameRef::DefaultGraph => Ok(EncodedTerm::DefaultGraph),
}
}
fn encode_quad(&mut self, quad: &Quad) -> Result<EncodedQuad<Self::StrId>, Self::Error> {
fn encode_quad(&mut self, quad: QuadRef<'_>) -> Result<EncodedQuad<Self::StrId>, Self::Error> {
Ok(EncodedQuad {
subject: self.encode_named_or_blank_node(&quad.subject)?,
predicate: self.encode_named_node(&quad.predicate)?,
object: self.encode_term(&quad.object)?,
graph_name: self.encode_graph_name(&quad.graph_name)?,
subject: self.encode_named_or_blank_node(quad.subject)?,
predicate: self.encode_named_node(quad.predicate)?,
object: self.encode_term(quad.object)?,
graph_name: self.encode_graph_name(quad.graph_name)?,
})
}
fn encode_triple_in_graph(
&mut self,
triple: &Triple,
triple: TripleRef<'_>,
graph_name: EncodedTerm<Self::StrId>,
) -> Result<EncodedQuad<Self::StrId>, Self::Error> {
Ok(EncodedQuad {
subject: self.encode_named_or_blank_node(&triple.subject)?,
predicate: self.encode_named_node(&triple.predicate)?,
object: self.encode_term(&triple.object)?,
subject: self.encode_named_or_blank_node(triple.subject)?,
predicate: self.encode_named_node(triple.predicate)?,
object: self.encode_term(triple.object)?,
graph_name,
})
}
@ -1433,16 +1433,19 @@ fn test_encoding() {
Literal::new_language_tagged_literal("foo-FR", "FR")
.unwrap()
.into(),
Literal::new_typed_literal("-1.32", xsd::DECIMAL.clone()).into(),
Literal::new_typed_literal("2020-01-01T01:01:01Z", xsd::DATE_TIME.clone()).into(),
Literal::new_typed_literal("2020-01-01", xsd::DATE.clone()).into(),
Literal::new_typed_literal("01:01:01Z", xsd::TIME.clone()).into(),
Literal::new_typed_literal("PT1S", xsd::DURATION.clone()).into(),
Literal::new_typed_literal("-1.32", xsd::DECIMAL).into(),
Literal::new_typed_literal("2020-01-01T01:01:01Z", xsd::DATE_TIME).into(),
Literal::new_typed_literal("2020-01-01", xsd::DATE).into(),
Literal::new_typed_literal("01:01:01Z", xsd::TIME).into(),
Literal::new_typed_literal("PT1S", xsd::DURATION).into(),
Literal::new_typed_literal("-foo", NamedNode::new_unchecked("http://foo.com")).into(),
];
for term in terms {
let encoded = store.encode_term(&term).unwrap();
assert_eq!(Some(encoded), store.get_encoded_term(&term).unwrap());
let encoded = store.encode_term(term.as_ref()).unwrap();
assert_eq!(
Some(encoded),
store.get_encoded_term(term.as_ref()).unwrap()
);
assert_eq!(term, store.decode_term(encoded).unwrap());
}
}

@ -125,10 +125,10 @@ impl RocksDbStore {
/// See `MemoryStore` for a usage example.
pub fn quads_for_pattern(
&self,
subject: Option<&NamedOrBlankNode>,
predicate: Option<&NamedNode>,
object: Option<&Term>,
graph_name: Option<&GraphName>,
subject: Option<NamedOrBlankNodeRef<'_>>,
predicate: Option<NamedNodeRef<'_>>,
object: Option<TermRef<'_>>,
graph_name: Option<GraphNameRef<'_>>,
) -> impl Iterator<Item = Result<Quad, io::Error>> {
match get_encoded_quad_pattern(self, subject, predicate, object, graph_name) {
Ok(Some((subject, predicate, object, graph_name))) => QuadsIter::Quads {
@ -141,8 +141,8 @@ impl RocksDbStore {
}
/// Checks if this store contains a given quad
pub fn contains(&self, quad: &Quad) -> Result<bool, io::Error> {
if let Some(quad) = self.get_encoded_quad(quad)? {
pub fn contains<'a>(&self, quad: impl Into<QuadRef<'a>>) -> Result<bool, io::Error> {
if let Some(quad) = self.get_encoded_quad(quad.into())? {
self.contains_encoded(&quad)
} else {
Ok(false)
@ -194,15 +194,21 @@ impl RocksDbStore {
/// Errors related to parameter validation like the base IRI use the `INVALID_INPUT` error kind.
/// Errors related to a bad syntax in the loaded file use the `INVALID_DATA` error kind.
/// Errors related to data loading into the store use the other error kinds.
pub fn load_graph(
pub fn load_graph<'a>(
&self,
reader: impl BufRead,
format: GraphFormat,
to_graph_name: &GraphName,
to_graph_name: impl Into<GraphNameRef<'a>>,
base_iri: Option<&str>,
) -> Result<(), io::Error> {
let mut transaction = self.auto_batch_writer();
load_graph(&mut transaction, reader, format, to_graph_name, base_iri)?;
load_graph(
&mut transaction,
reader,
format,
to_graph_name.into(),
base_iri,
)?;
Ok(transaction.apply()?)
}
@ -228,16 +234,16 @@ impl RocksDbStore {
}
/// Adds a quad to this store.
pub fn insert(&self, quad: &Quad) -> Result<(), io::Error> {
pub fn insert<'a>(&self, quad: impl Into<QuadRef<'a>>) -> Result<(), io::Error> {
let mut transaction = self.auto_batch_writer();
let quad = transaction.encode_quad(quad)?;
let quad = transaction.encode_quad(quad.into())?;
transaction.insert_encoded(&quad)?;
transaction.apply()
}
/// Removes a quad from this store.
pub fn remove(&self, quad: &Quad) -> Result<(), io::Error> {
if let Some(quad) = self.get_encoded_quad(quad)? {
pub fn remove<'a>(&self, quad: impl Into<QuadRef<'a>>) -> Result<(), io::Error> {
if let Some(quad) = self.get_encoded_quad(quad.into())? {
let mut transaction = self.auto_batch_writer();
transaction.remove_encoded(&quad)?;
transaction.apply()
@ -249,14 +255,14 @@ impl RocksDbStore {
/// Dumps a store graph into a file.
///
/// See `MemoryStore` for a usage example.
pub fn dump_graph(
pub fn dump_graph<'a>(
&self,
writer: impl Write,
format: GraphFormat,
from_graph_name: &GraphName,
from_graph_name: impl Into<GraphNameRef<'a>>,
) -> Result<(), io::Error> {
dump_graph(
self.quads_for_pattern(None, None, None, Some(from_graph_name))
self.quads_for_pattern(None, None, None, Some(from_graph_name.into()))
.map(|q| Ok(q?.into())),
writer,
format,
@ -696,14 +702,14 @@ impl RocksDbTransaction<'_> {
///
/// Errors related to parameter validation like the base IRI use the `INVALID_INPUT` error kind.
/// Errors related to a bad syntax in the loaded file use the `INVALID_DATA` error kind.
pub fn load_graph(
pub fn load_graph<'a>(
&mut self,
reader: impl BufRead,
syntax: GraphFormat,
to_graph_name: &GraphName,
to_graph_name: impl Into<GraphNameRef<'a>>,
base_iri: Option<&str>,
) -> Result<(), io::Error> {
load_graph(self, reader, syntax, to_graph_name, base_iri)?;
load_graph(self, reader, syntax, to_graph_name.into(), base_iri)?;
Ok(())
}
@ -728,15 +734,15 @@ impl RocksDbTransaction<'_> {
}
/// Adds a quad to this store during the transaction.
pub fn insert(&mut self, quad: &Quad) -> Result<(), io::Error> {
let quad = self.encode_quad(quad)?;
pub fn insert<'a>(&mut self, quad: impl Into<QuadRef<'a>>) -> Result<(), io::Error> {
let quad = self.encode_quad(quad.into())?;
self.insert_encoded(&quad)
}
/// Removes a quad from this store during the transaction.
pub fn remove(&mut self, quad: &Quad) -> Result<(), io::Error> {
pub fn remove<'a>(&mut self, quad: impl Into<QuadRef<'a>>) -> Result<(), io::Error> {
// Works because all strings could be encoded
if let Some(quad) = self.get_encoded_quad(quad).unwrap() {
if let Some(quad) = self.get_encoded_quad(quad.into()).unwrap() {
self.remove_encoded(&quad)
} else {
Ok(())
@ -1060,29 +1066,34 @@ fn store() -> Result<(), io::Error> {
);
assert_eq!(
store
.quads_for_pattern(Some(&main_s), None, None, None)
.quads_for_pattern(Some(main_s.as_ref()), None, None, None)
.collect::<Result<Vec<_>, _>>()?,
all_o
);
assert_eq!(
store
.quads_for_pattern(Some(&main_s), Some(&main_p), None, None)
.quads_for_pattern(Some(main_s.as_ref()), Some(main_p.as_ref()), None, None)
.collect::<Result<Vec<_>, _>>()?,
all_o
);
assert_eq!(
store
.quads_for_pattern(Some(&main_s), Some(&main_p), Some(&main_o), None)
.quads_for_pattern(
Some(main_s.as_ref()),
Some(main_p.as_ref()),
Some(main_o.as_ref()),
None
)
.collect::<Result<Vec<_>, _>>()?,
target
);
assert_eq!(
store
.quads_for_pattern(
Some(&main_s),
Some(&main_p),
Some(&main_o),
Some(&GraphName::DefaultGraph)
Some(main_s.as_ref()),
Some(main_p.as_ref()),
Some(main_o.as_ref()),
Some(GraphNameRef::DefaultGraph)
)
.collect::<Result<Vec<_>, _>>()?,
target
@ -1090,58 +1101,63 @@ fn store() -> Result<(), io::Error> {
assert_eq!(
store
.quads_for_pattern(
Some(&main_s),
Some(&main_p),
Some(main_s.as_ref()),
Some(main_p.as_ref()),
None,
Some(&GraphName::DefaultGraph)
Some(GraphNameRef::DefaultGraph)
)
.collect::<Result<Vec<_>, _>>()?,
all_o
);
assert_eq!(
store
.quads_for_pattern(Some(&main_s), None, Some(&main_o), None)
.quads_for_pattern(Some(main_s.as_ref()), None, Some(main_o.as_ref()), None)
.collect::<Result<Vec<_>, _>>()?,
target
);
assert_eq!(
store
.quads_for_pattern(
Some(&main_s),
Some(main_s.as_ref()),
None,
Some(&main_o),
Some(&GraphName::DefaultGraph)
Some(main_o.as_ref()),
Some(GraphNameRef::DefaultGraph)
)
.collect::<Result<Vec<_>, _>>()?,
target
);
assert_eq!(
store
.quads_for_pattern(Some(&main_s), None, None, Some(&GraphName::DefaultGraph))
.quads_for_pattern(
Some(main_s.as_ref()),
None,
None,
Some(GraphNameRef::DefaultGraph)
)
.collect::<Result<Vec<_>, _>>()?,
all_o
);
assert_eq!(
store
.quads_for_pattern(None, Some(&main_p), None, None)
.quads_for_pattern(None, Some(main_p.as_ref()), None, None)
.collect::<Result<Vec<_>, _>>()?,
all_o
);
assert_eq!(
store
.quads_for_pattern(None, Some(&main_p), Some(&main_o), None)
.quads_for_pattern(None, Some(main_p.as_ref()), Some(main_o.as_ref()), None)
.collect::<Result<Vec<_>, _>>()?,
target
);
assert_eq!(
store
.quads_for_pattern(None, None, Some(&main_o), None)
.quads_for_pattern(None, None, Some(main_o.as_ref()), None)
.collect::<Result<Vec<_>, _>>()?,
target
);
assert_eq!(
store
.quads_for_pattern(None, None, None, Some(&GraphName::DefaultGraph))
.quads_for_pattern(None, None, None, Some(GraphNameRef::DefaultGraph))
.collect::<Result<Vec<_>, _>>()?,
all_o
);
@ -1149,9 +1165,9 @@ fn store() -> Result<(), io::Error> {
store
.quads_for_pattern(
None,
Some(&main_p),
Some(&main_o),
Some(&GraphName::DefaultGraph)
Some(main_p.as_ref()),
Some(main_o.as_ref()),
Some(GraphNameRef::DefaultGraph)
)
.collect::<Result<Vec<_>, _>>()?,
target

@ -126,10 +126,10 @@ impl SledStore {
/// See `MemoryStore` for a usage example.
pub fn quads_for_pattern(
&self,
subject: Option<&NamedOrBlankNode>,
predicate: Option<&NamedNode>,
object: Option<&Term>,
graph_name: Option<&GraphName>,
subject: Option<NamedOrBlankNodeRef<'_>>,
predicate: Option<NamedNodeRef<'_>>,
object: Option<TermRef<'_>>,
graph_name: Option<GraphNameRef<'_>>,
) -> impl Iterator<Item = Result<Quad, io::Error>> {
match get_encoded_quad_pattern(self, subject, predicate, object, graph_name) {
Ok(Some((subject, predicate, object, graph_name))) => QuadsIter::Quads {
@ -142,8 +142,8 @@ impl SledStore {
}
/// Checks if this store contains a given quad
pub fn contains(&self, quad: &Quad) -> Result<bool, io::Error> {
if let Some(quad) = self.get_encoded_quad(quad)? {
pub fn contains<'a>(&self, quad: impl Into<QuadRef<'a>>) -> Result<bool, io::Error> {
if let Some(quad) = self.get_encoded_quad(quad.into())? {
self.contains_encoded(&quad)
} else {
Ok(false)
@ -205,15 +205,15 @@ impl SledStore {
/// Errors related to parameter validation like the base IRI use the `INVALID_INPUT` error kind.
/// Errors related to a bad syntax in the loaded file use the `INVALID_DATA` error kind.
/// Errors related to data loading into the store use the other error kinds.
pub fn load_graph(
pub fn load_graph<'a>(
&self,
reader: impl BufRead,
format: GraphFormat,
to_graph_name: &GraphName,
to_graph_name: impl Into<GraphNameRef<'a>>,
base_iri: Option<&str>,
) -> Result<(), io::Error> {
let mut this = self;
load_graph(&mut this, reader, format, to_graph_name, base_iri)?;
load_graph(&mut this, reader, format, to_graph_name.into(), base_iri)?;
Ok(())
}
@ -239,15 +239,15 @@ impl SledStore {
}
/// Adds a quad to this store.
pub fn insert(&self, quad: &Quad) -> Result<(), io::Error> {
pub fn insert<'a>(&self, quad: impl Into<QuadRef<'a>>) -> Result<(), io::Error> {
let mut this = self;
let quad = this.encode_quad(quad)?;
let quad = this.encode_quad(quad.into())?;
this.insert_encoded(&quad)
}
/// Removes a quad from this store.
pub fn remove(&self, quad: &Quad) -> Result<(), io::Error> {
if let Some(quad) = self.get_encoded_quad(quad)? {
pub fn remove<'a>(&self, quad: impl Into<QuadRef<'a>>) -> Result<(), io::Error> {
if let Some(quad) = self.get_encoded_quad(quad.into())? {
let mut this = self;
this.remove_encoded(&quad)
} else {
@ -258,14 +258,14 @@ impl SledStore {
/// Dumps a store graph into a file.
///
/// See `MemoryStore` for a usage example.
pub fn dump_graph(
pub fn dump_graph<'a>(
&self,
writer: impl Write,
format: GraphFormat,
from_graph_name: &GraphName,
from_graph_name: impl Into<GraphNameRef<'a>>,
) -> Result<(), io::Error> {
dump_graph(
self.quads_for_pattern(None, None, None, Some(from_graph_name))
self.quads_for_pattern(None, None, None, Some(from_graph_name.into()))
.map(|q| Ok(q?.into())),
writer,
format,
@ -601,15 +601,15 @@ impl SledTransaction<'_> {
///
/// Errors related to parameter validation like the base IRI use the `INVALID_INPUT` error kind.
/// Errors related to a bad syntax in the loaded file use the `INVALID_DATA` error kind.
pub fn load_graph(
pub fn load_graph<'a>(
&self,
reader: impl BufRead,
format: GraphFormat,
to_graph_name: &GraphName,
to_graph_name: impl Into<GraphNameRef<'a>>,
base_iri: Option<&str>,
) -> Result<(), SledUnabortableTransactionError> {
let mut this = self;
load_graph(&mut this, reader, format, to_graph_name, base_iri)?;
load_graph(&mut this, reader, format, to_graph_name.into(), base_iri)?;
Ok(())
}
@ -635,16 +635,22 @@ impl SledTransaction<'_> {
}
/// Adds a quad to this store during the transaction.
pub fn insert(&self, quad: &Quad) -> Result<(), SledUnabortableTransactionError> {
pub fn insert<'a>(
&self,
quad: impl Into<QuadRef<'a>>,
) -> Result<(), SledUnabortableTransactionError> {
let mut this = self;
let quad = this.encode_quad(quad)?;
let quad = this.encode_quad(quad.into())?;
this.insert_encoded(&quad)
}
/// Removes a quad from this store during the transaction.
pub fn remove(&self, quad: &Quad) -> Result<(), SledUnabortableTransactionError> {
pub fn remove<'a>(
&self,
quad: impl Into<QuadRef<'a>>,
) -> Result<(), SledUnabortableTransactionError> {
let mut this = self;
if let Some(quad) = this.get_encoded_quad(quad)? {
if let Some(quad) = this.get_encoded_quad(quad.into())? {
this.remove_encoded(&quad)
} else {
Ok(())
@ -1080,29 +1086,34 @@ fn store() -> Result<(), io::Error> {
);
assert_eq!(
store
.quads_for_pattern(Some(&main_s), None, None, None)
.quads_for_pattern(Some(main_s.as_ref()), None, None, None)
.collect::<Result<Vec<_>, _>>()?,
all_o
);
assert_eq!(
store
.quads_for_pattern(Some(&main_s), Some(&main_p), None, None)
.quads_for_pattern(Some(main_s.as_ref()), Some(main_p.as_ref()), None, None)
.collect::<Result<Vec<_>, _>>()?,
all_o
);
assert_eq!(
store
.quads_for_pattern(Some(&main_s), Some(&main_p), Some(&main_o), None)
.quads_for_pattern(
Some(main_s.as_ref()),
Some(main_p.as_ref()),
Some(main_o.as_ref()),
None
)
.collect::<Result<Vec<_>, _>>()?,
target
);
assert_eq!(
store
.quads_for_pattern(
Some(&main_s),
Some(&main_p),
Some(&main_o),
Some(&GraphName::DefaultGraph)
Some(main_s.as_ref()),
Some(main_p.as_ref()),
Some(main_o.as_ref()),
Some(GraphNameRef::DefaultGraph)
)
.collect::<Result<Vec<_>, _>>()?,
target
@ -1110,58 +1121,63 @@ fn store() -> Result<(), io::Error> {
assert_eq!(
store
.quads_for_pattern(
Some(&main_s),
Some(&main_p),
Some(main_s.as_ref()),
Some(main_p.as_ref()),
None,
Some(&GraphName::DefaultGraph)
Some(GraphNameRef::DefaultGraph)
)
.collect::<Result<Vec<_>, _>>()?,
all_o
);
assert_eq!(
store
.quads_for_pattern(Some(&main_s), None, Some(&main_o), None)
.quads_for_pattern(Some(main_s.as_ref()), None, Some(main_o.as_ref()), None)
.collect::<Result<Vec<_>, _>>()?,
target
);
assert_eq!(
store
.quads_for_pattern(
Some(&main_s),
Some(main_s.as_ref()),
None,
Some(&main_o),
Some(&GraphName::DefaultGraph)
Some(main_o.as_ref()),
Some(GraphNameRef::DefaultGraph)
)
.collect::<Result<Vec<_>, _>>()?,
target
);
assert_eq!(
store
.quads_for_pattern(Some(&main_s), None, None, Some(&GraphName::DefaultGraph))
.quads_for_pattern(
Some(main_s.as_ref()),
None,
None,
Some(GraphNameRef::DefaultGraph)
)
.collect::<Result<Vec<_>, _>>()?,
all_o
);
assert_eq!(
store
.quads_for_pattern(None, Some(&main_p), None, None)
.quads_for_pattern(None, Some(main_p.as_ref()), None, None)
.collect::<Result<Vec<_>, _>>()?,
all_o
);
assert_eq!(
store
.quads_for_pattern(None, Some(&main_p), Some(&main_o), None)
.quads_for_pattern(None, Some(main_p.as_ref()), Some(main_o.as_ref()), None)
.collect::<Result<Vec<_>, _>>()?,
target
);
assert_eq!(
store
.quads_for_pattern(None, None, Some(&main_o), None)
.quads_for_pattern(None, None, Some(main_o.as_ref()), None)
.collect::<Result<Vec<_>, _>>()?,
target
);
assert_eq!(
store
.quads_for_pattern(None, None, None, Some(&GraphName::DefaultGraph))
.quads_for_pattern(None, None, None, Some(GraphNameRef::DefaultGraph))
.collect::<Result<Vec<_>, _>>()?,
all_o
);
@ -1169,9 +1185,9 @@ fn store() -> Result<(), io::Error> {
store
.quads_for_pattern(
None,
Some(&main_p),
Some(&main_o),
Some(&GraphName::DefaultGraph)
Some(main_p.as_ref()),
Some(main_o.as_ref()),
Some(GraphNameRef::DefaultGraph)
)
.collect::<Result<Vec<_>, _>>()?,
target

@ -47,10 +47,10 @@ impl PyMemoryStore {
extract_quads_pattern(subject, predicate, object, graph_name)?;
Ok(QuadIter {
inner: Box::new(self.inner.quads_for_pattern(
subject.as_ref(),
predicate.as_ref(),
object.as_ref(),
graph_name.as_ref(),
subject.as_ref().map(|t| t.into()),
predicate.as_ref().map(|t| t.into()),
object.as_ref().map(|t| t.into()),
graph_name.as_ref().map(|t| t.into()),
)),
})
}

@ -214,7 +214,7 @@ impl PyLiteral {
#[getter]
fn datatype(&self) -> PyNamedNode {
self.inner.datatype().clone().into()
self.inner.datatype().into_owned().into()
}
}

@ -49,10 +49,10 @@ impl PySledStore {
extract_quads_pattern(subject, predicate, object, graph_name)?;
Ok(QuadIter {
inner: Box::new(self.inner.quads_for_pattern(
subject.as_ref(),
predicate.as_ref(),
object.as_ref(),
graph_name.as_ref(),
subject.as_ref().map(|t| t.into()),
predicate.as_ref().map(|t| t.into()),
object.as_ref().map(|t| t.into()),
graph_name.as_ref().map(|t| t.into()),
)),
})
}

@ -14,7 +14,6 @@ publish = false
[dependencies]
anyhow = "1"
chrono = "0.4"
lazy_static = "1"
oxigraph = { path = "../lib" }
[dev-dependencies]

@ -72,57 +72,50 @@ impl Iterator for TestManifest {
fn next(&mut self) -> Option<Result<Test>> {
match self.tests_to_do.pop() {
Some(Term::NamedNode(test_node)) => {
let test_subject = NamedOrBlankNode::from(test_node.clone());
let kind =
match object_for_subject_predicate(&self.graph, &test_subject, &rdf::TYPE) {
let kind = match object_for_subject_predicate(&self.graph, &test_node, rdf::TYPE) {
Some(Term::NamedNode(c)) => c,
_ => return self.next(), //We ignore the test
};
let name = match object_for_subject_predicate(&self.graph, &test_subject, &mf::NAME)
{
let name = match object_for_subject_predicate(&self.graph, &test_node, mf::NAME) {
Some(Term::Literal(c)) => Some(c.value().to_string()),
_ => None,
};
let comment = match object_for_subject_predicate(
&self.graph,
&test_subject,
&rdfs::COMMENT,
) {
let comment =
match object_for_subject_predicate(&self.graph, &test_node, rdfs::COMMENT) {
Some(Term::Literal(c)) => Some(c.value().to_string()),
_ => None,
};
let (action, query, data, graph_data, service_data) =
match object_for_subject_predicate(&self.graph, &test_subject, &*mf::ACTION) {
match object_for_subject_predicate(&self.graph, &test_node, mf::ACTION) {
Some(Term::NamedNode(n)) => {
(Some(n.into_string()), None, None, vec![], vec![])
}
Some(Term::BlankNode(n)) => {
let n = n.into();
let query =
match object_for_subject_predicate(&self.graph, &n, &qt::QUERY) {
match object_for_subject_predicate(&self.graph, &n, qt::QUERY) {
Some(Term::NamedNode(q)) => Some(q.into_string()),
_ => None,
};
let data =
match object_for_subject_predicate(&self.graph, &n, &qt::DATA) {
let data = match object_for_subject_predicate(&self.graph, &n, qt::DATA)
{
Some(Term::NamedNode(q)) => Some(q.into_string()),
_ => None,
};
let graph_data =
objects_for_subject_predicate(&self.graph, &n, &qt::GRAPH_DATA)
objects_for_subject_predicate(&self.graph, &n, qt::GRAPH_DATA)
.filter_map(|g| match g {
Term::NamedNode(q) => Some(q.into_string()),
_ => None,
})
.collect();
let service_data =
objects_for_subject_predicate(&self.graph, &n, &qt::SERVICE_DATA)
objects_for_subject_predicate(&self.graph, &n, qt::SERVICE_DATA)
.filter_map(|g| match g {
Term::NamedNode(g) => Some(g.into()),
Term::BlankNode(g) => Some(g.into()),
_ => None,
})
.filter_map(|g| {
.filter_map(|g: NamedOrBlankNode| {
if let (
Some(Term::NamedNode(endpoint)),
Some(Term::NamedNode(data)),
@ -130,13 +123,9 @@ impl Iterator for TestManifest {
object_for_subject_predicate(
&self.graph,
&g,
&qt::ENDPOINT,
),
object_for_subject_predicate(
&self.graph,
&g,
&qt::DATA,
qt::ENDPOINT,
),
object_for_subject_predicate(&self.graph, &g, qt::DATA),
) {
Some((endpoint.into_string(), data.into_string()))
} else {
@ -148,14 +137,11 @@ impl Iterator for TestManifest {
}
Some(_) => return Some(Err(anyhow!("invalid action"))),
None => {
return Some(Err(anyhow!(
"action not found for test {}",
test_subject
)));
return Some(Err(anyhow!("action not found for test {}", test_node)));
}
};
let result =
match object_for_subject_predicate(&self.graph, &test_subject, &*mf::RESULT) {
let result = match object_for_subject_predicate(&self.graph, &test_node, mf::RESULT)
{
Some(Term::NamedNode(n)) => Some(n.into_string()),
Some(_) => return Some(Err(anyhow!("invalid result"))),
None => None,
@ -177,7 +163,8 @@ impl Iterator for TestManifest {
None => {
match self.manifests_to_do.pop() {
Some(url) => {
let manifest = NamedOrBlankNode::from(NamedNode::new(url.clone()).unwrap());
let manifest =
NamedOrBlankNodeRef::from(NamedNodeRef::new(url.as_str()).unwrap());
if let Err(error) =
load_to_store(&url, &self.graph, &&GraphName::DefaultGraph)
{
@ -185,7 +172,7 @@ impl Iterator for TestManifest {
}
// New manifests
match object_for_subject_predicate(&self.graph, &manifest, &*mf::INCLUDE) {
match object_for_subject_predicate(&self.graph, manifest, mf::INCLUDE) {
Some(Term::BlankNode(list)) => {
self.manifests_to_do.extend(
RdfListIterator::iter(&self.graph, list.into()).filter_map(
@ -201,7 +188,7 @@ impl Iterator for TestManifest {
}
// New tests
match object_for_subject_predicate(&self.graph, &manifest, &*mf::ENTRIES) {
match object_for_subject_predicate(&self.graph, manifest, mf::ENTRIES) {
Some(Term::BlankNode(list)) => {
self.tests_to_do
.extend(RdfListIterator::iter(&self.graph, list.into()));
@ -240,10 +227,10 @@ impl<'a> Iterator for RdfListIterator<'a> {
fn next(&mut self) -> Option<Term> {
match self.current_node.clone() {
Some(current) => {
let result = object_for_subject_predicate(&self.graph, &current, &rdf::FIRST);
let result = object_for_subject_predicate(&self.graph, &current, rdf::FIRST);
self.current_node =
match object_for_subject_predicate(&self.graph, &current, &rdf::REST) {
Some(Term::NamedNode(ref n)) if *n == *rdf::NIL => None,
match object_for_subject_predicate(&self.graph, &current, rdf::REST) {
Some(Term::NamedNode(n)) if n == rdf::NIL => None,
Some(Term::NamedNode(n)) => Some(n.into()),
Some(Term::BlankNode(n)) => Some(n.into()),
_ => None,
@ -255,20 +242,20 @@ impl<'a> Iterator for RdfListIterator<'a> {
}
}
fn object_for_subject_predicate(
fn object_for_subject_predicate<'a>(
store: &MemoryStore,
subject: &NamedOrBlankNode,
predicate: &NamedNode,
subject: impl Into<NamedOrBlankNodeRef<'a>>,
predicate: impl Into<NamedNodeRef<'a>>,
) -> Option<Term> {
objects_for_subject_predicate(store, subject, predicate).next()
}
fn objects_for_subject_predicate(
fn objects_for_subject_predicate<'a>(
store: &MemoryStore,
subject: &NamedOrBlankNode,
predicate: &NamedNode,
subject: impl Into<NamedOrBlankNodeRef<'a>>,
predicate: impl Into<NamedNodeRef<'a>>,
) -> impl Iterator<Item = Term> {
store
.quads_for_pattern(Some(subject), Some(predicate), None, None)
.quads_for_pattern(Some(subject.into()), Some(predicate.into()), None, None)
.map(|t| t.object)
}

@ -200,13 +200,13 @@ fn to_dataset(result: QueryResult, with_order: bool) -> Result<MemoryStore> {
let result_set = BlankNode::default();
store.insert(Quad::new(
result_set.clone(),
rdf::TYPE.clone(),
rs::RESULT_SET.clone(),
rdf::TYPE,
rs::RESULT_SET,
None,
));
store.insert(Quad::new(
result_set,
rs::BOOLEAN.clone(),
rs::BOOLEAN,
Literal::from(value),
None,
));
@ -217,14 +217,14 @@ fn to_dataset(result: QueryResult, with_order: bool) -> Result<MemoryStore> {
let result_set = BlankNode::default();
store.insert(Quad::new(
result_set.clone(),
rdf::TYPE.clone(),
rs::RESULT_SET.clone(),
rdf::TYPE,
rs::RESULT_SET,
None,
));
for variable in solutions.variables() {
store.insert(Quad::new(
result_set.clone(),
rs::RESULT_VARIABLE.clone(),
rs::RESULT_VARIABLE,
Literal::new_simple_literal(variable.as_str()),
None,
));
@ -234,7 +234,7 @@ fn to_dataset(result: QueryResult, with_order: bool) -> Result<MemoryStore> {
let solution_id = BlankNode::default();
store.insert(Quad::new(
result_set.clone(),
rs::SOLUTION.clone(),
rs::SOLUTION,
solution_id.clone(),
None,
));
@ -242,19 +242,14 @@ fn to_dataset(result: QueryResult, with_order: bool) -> Result<MemoryStore> {
let binding = BlankNode::default();
store.insert(Quad::new(
solution_id.clone(),
rs::BINDING.clone(),
rs::BINDING,
binding.clone(),
None,
));
store.insert(Quad::new(
binding.clone(),
rs::VALUE.clone(),
value.clone(),
None,
));
store.insert(Quad::new(binding.clone(), rs::VALUE, value.clone(), None));
store.insert(Quad::new(
binding,
rs::VARIABLE.clone(),
rs::VARIABLE,
Literal::new_simple_literal(variable.as_str()),
None,
));
@ -262,7 +257,7 @@ fn to_dataset(result: QueryResult, with_order: bool) -> Result<MemoryStore> {
if with_order {
store.insert(Quad::new(
solution_id,
rs::INDEX.clone(),
rs::INDEX,
Literal::from((i + 1) as i128),
None,
));
@ -374,28 +369,19 @@ impl StaticQueryResults {
fn from_dataset(dataset: MemoryStore) -> StaticQueryResults {
if let Some(result_set) = dataset
.quads_for_pattern(
None,
Some(&rdf::TYPE),
Some(&rs::RESULT_SET.clone().into()),
None,
)
.quads_for_pattern(None, Some(rdf::TYPE), Some(rs::RESULT_SET.into()), None)
.map(|q| q.subject)
.next()
{
if let Some(bool) = dataset
.quads_for_pattern(Some(&result_set), Some(&rs::BOOLEAN), None, None)
.map(|q| q.object)
.next()
{
if let Some(bool) = object_for_subject_predicate(&dataset, &result_set, rs::BOOLEAN) {
// Boolean query
StaticQueryResults::Boolean(bool == Literal::from(true).into())
} else {
// Regular query
let mut variables: Vec<Variable> = dataset
.quads_for_pattern(Some(&result_set), Some(&rs::RESULT_VARIABLE), None, None)
.filter_map(|q| {
if let Term::Literal(l) = q.object {
let mut variables: Vec<Variable> =
objects_for_subject_predicate(&dataset, &result_set, rs::RESULT_VARIABLE)
.filter_map(|object| {
if let Term::Literal(l) = object {
Some(Variable::new(l.value()))
} else {
None
@ -404,35 +390,28 @@ impl StaticQueryResults {
.collect();
variables.sort();
let mut solutions: Vec<_> = dataset
.quads_for_pattern(Some(&result_set), Some(&rs::SOLUTION), None, None)
.filter_map(|q| {
if let Term::BlankNode(solution) = q.object {
let solution = solution.into();
let mut bindings = dataset
.quads_for_pattern(Some(&solution), Some(&rs::BINDING), None, None)
.filter_map(|q| {
if let Term::BlankNode(binding) = q.object {
let binding = binding.into();
if let (Some(Term::Literal(variable)), Some(value)) = (
dataset
.quads_for_pattern(
Some(&binding),
Some(&rs::VARIABLE),
None,
None,
)
.map(|q| q.object)
.next(),
dataset
.quads_for_pattern(
Some(&binding),
Some(&rs::VALUE),
None,
None,
)
.map(|q| q.object)
.next(),
let mut solutions: Vec<_> =
objects_for_subject_predicate(&dataset, &result_set, rs::SOLUTION)
.filter_map(|object| {
if let Term::BlankNode(solution) = object {
let mut bindings =
objects_for_subject_predicate(&dataset, &solution, rs::BINDING)
.filter_map(|object| {
if let Term::BlankNode(binding) = object {
if let (
Some(Term::Literal(variable)),
Some(value),
) = (
object_for_subject_predicate(
&dataset,
&binding,
rs::VARIABLE,
),
object_for_subject_predicate(
&dataset,
&binding,
rs::VALUE,
),
) {
Some((Variable::new(variable.value()), value))
} else {
@ -444,16 +423,15 @@ impl StaticQueryResults {
})
.collect::<Vec<_>>();
bindings.sort_by(|(a, _), (b, _)| a.cmp(&b));
let index = dataset
.quads_for_pattern(Some(&solution), Some(&rs::INDEX), None, None)
.filter_map(|q| {
if let Term::Literal(l) = q.object {
let index =
object_for_subject_predicate(&dataset, &solution, rs::INDEX)
.and_then(|object| {
if let Term::Literal(l) = object {
u64::from_str(l.value()).ok()
} else {
None
}
})
.next();
});
Some((bindings, index))
} else {
None
@ -478,3 +456,21 @@ impl StaticQueryResults {
}
}
}
fn object_for_subject_predicate<'a>(
store: &MemoryStore,
subject: impl Into<NamedOrBlankNodeRef<'a>>,
predicate: impl Into<NamedNodeRef<'a>>,
) -> Option<Term> {
objects_for_subject_predicate(store, subject, predicate).next()
}
fn objects_for_subject_predicate<'a>(
store: &MemoryStore,
subject: impl Into<NamedOrBlankNodeRef<'a>>,
predicate: impl Into<NamedNodeRef<'a>>,
) -> impl Iterator<Item = Term> {
store
.quads_for_pattern(Some(subject.into()), Some(predicate.into()), None, None)
.map(|t| t.object)
}

@ -1,73 +1,64 @@
pub mod rs {
use lazy_static::lazy_static;
use oxigraph::model::NamedNode;
use oxigraph::model::NamedNodeRef;
lazy_static! {
pub static ref RESULT_SET: NamedNode =
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/result-set#ResultSet")
.unwrap();
pub static ref RESULT_VARIABLE: NamedNode =
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/result-set#resultVariable")
.unwrap();
pub static ref SOLUTION: NamedNode =
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/result-set#solution")
.unwrap();
pub static ref BINDING: NamedNode =
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/result-set#binding")
.unwrap();
pub static ref VALUE: NamedNode =
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/result-set#value").unwrap();
pub static ref VARIABLE: NamedNode =
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/result-set#variable")
.unwrap();
pub static ref INDEX: NamedNode =
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/result-set#index").unwrap();
pub static ref BOOLEAN: NamedNode =
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/result-set#boolean")
.unwrap();
}
pub const RESULT_SET: NamedNodeRef<'_> = NamedNodeRef::new_unchecked(
"http://www.w3.org/2001/sw/DataAccess/tests/result-set#ResultSet",
);
pub const RESULT_VARIABLE: NamedNodeRef<'_> = NamedNodeRef::new_unchecked(
"http://www.w3.org/2001/sw/DataAccess/tests/result-set#resultVariable",
);
pub const SOLUTION: NamedNodeRef<'_> = NamedNodeRef::new_unchecked(
"http://www.w3.org/2001/sw/DataAccess/tests/result-set#solution",
);
pub const BINDING: NamedNodeRef<'_> = NamedNodeRef::new_unchecked(
"http://www.w3.org/2001/sw/DataAccess/tests/result-set#binding",
);
pub const VALUE: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/sw/DataAccess/tests/result-set#value");
pub const VARIABLE: NamedNodeRef<'_> = NamedNodeRef::new_unchecked(
"http://www.w3.org/2001/sw/DataAccess/tests/result-set#variable",
);
pub const INDEX: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/sw/DataAccess/tests/result-set#index");
pub const BOOLEAN: NamedNodeRef<'_> = NamedNodeRef::new_unchecked(
"http://www.w3.org/2001/sw/DataAccess/tests/result-set#boolean",
);
}
pub mod mf {
use lazy_static::lazy_static;
use oxigraph::model::NamedNode;
use oxigraph::model::NamedNodeRef;
lazy_static! {
pub static ref INCLUDE: NamedNode =
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#include")
.unwrap();
pub static ref ENTRIES: NamedNode =
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#entries")
.unwrap();
pub static ref NAME: NamedNode =
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#name")
.unwrap();
pub static ref ACTION: NamedNode =
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#action")
.unwrap();
pub static ref RESULT: NamedNode =
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#result")
.unwrap();
}
pub const INCLUDE: NamedNodeRef<'_> = NamedNodeRef::new_unchecked(
"http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#include",
);
pub const ENTRIES: NamedNodeRef<'_> = NamedNodeRef::new_unchecked(
"http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#entries",
);
pub const NAME: NamedNodeRef<'_> = NamedNodeRef::new_unchecked(
"http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#name",
);
pub const ACTION: NamedNodeRef<'_> = NamedNodeRef::new_unchecked(
"http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#action",
);
pub const RESULT: NamedNodeRef<'_> = NamedNodeRef::new_unchecked(
"http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#result",
);
}
pub mod qt {
use lazy_static::lazy_static;
use oxigraph::model::NamedNode;
use oxigraph::model::NamedNodeRef;
lazy_static! {
pub static ref QUERY: NamedNode =
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/test-query#query").unwrap();
pub static ref DATA: NamedNode =
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/test-query#data").unwrap();
pub static ref GRAPH_DATA: NamedNode =
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/test-query#graphData")
.unwrap();
pub static ref SERVICE_DATA: NamedNode =
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/test-query#serviceData")
.unwrap();
pub static ref ENDPOINT: NamedNode =
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/test-query#endpoint")
.unwrap();
}
pub const QUERY: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/sw/DataAccess/tests/test-query#query");
pub const DATA: NamedNodeRef<'_> =
NamedNodeRef::new_unchecked("http://www.w3.org/2001/sw/DataAccess/tests/test-query#data");
pub const GRAPH_DATA: NamedNodeRef<'_> = NamedNodeRef::new_unchecked(
"http://www.w3.org/2001/sw/DataAccess/tests/test-query#graphData",
);
pub const SERVICE_DATA: NamedNodeRef<'_> = NamedNodeRef::new_unchecked(
"http://www.w3.org/2001/sw/DataAccess/tests/test-query#serviceData",
);
pub const ENDPOINT: NamedNodeRef<'_> = NamedNodeRef::new_unchecked(
"http://www.w3.org/2001/sw/DataAccess/tests/test-query#endpoint",
);
}

@ -6,7 +6,7 @@ use http_client::h1::H1Client;
use http_client::HttpClient;
use http_types::{headers, Method, Request, Result};
use oxigraph::io::GraphFormat;
use oxigraph::model::NamedNode;
use oxigraph::model::NamedNodeRef;
use oxigraph::RocksDbStore;
use serde_json::Value;
use std::collections::{HashMap, HashSet};
@ -230,11 +230,11 @@ impl WikibaseLoader {
}
fn load_entity_data(&self, uri: &str, data: impl Read) -> Result<()> {
let graph_name = NamedNode::new(uri)?.into();
let graph_name = NamedNodeRef::new(uri)?.into();
self.store.transaction(|transaction| {
let to_remove = self
.store
.quads_for_pattern(None, None, None, Some(&graph_name))
.quads_for_pattern(None, None, None, Some(graph_name))
.collect::<std::result::Result<Vec<_>, _>>()?;
for q in to_remove {
transaction.remove(&q)?;
@ -243,7 +243,7 @@ impl WikibaseLoader {
transaction.load_graph(
BufReader::new(data),
GraphFormat::NTriples,
&NamedNode::new(uri)?.into(),
NamedNodeRef::new(uri)?,
None,
)?;
Ok(())

Loading…
Cancel
Save