Explodes model::data module

pull/10/head
Tpt 7 years ago
parent 1800d6deca
commit 53a5a7df10
  1. 30
      src/model/blank_node.rs
  2. 140
      src/model/literal.rs
  3. 17
      src/model/mod.rs
  4. 57
      src/model/named_node.rs
  5. 234
      src/model/triple.rs
  6. 6
      src/model/vocab.rs
  7. 2
      src/rio/ntriples/mod.rs
  8. 2
      src/rio/ntriples/ntriples_grammar.rustpeg
  9. 2
      src/rio/turtle/mod.rs
  10. 2
      src/sparql/ast.rs
  11. 2
      src/sparql/model.rs
  12. 2
      src/sparql/parser.rs
  13. 2
      src/store/isomorphism.rs
  14. 2
      src/store/memory.rs
  15. 4
      tests/rdf_test_cases.rs

@ -0,0 +1,30 @@
use std::fmt;
use std::ops::Deref;
use uuid::Uuid;
/// A RDF [blank node](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node)
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub struct BlankNode {
id: Uuid,
}
impl Deref for BlankNode {
type Target = Uuid;
fn deref(&self) -> &Uuid {
&self.id
}
}
impl fmt::Display for BlankNode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "_:{}", self.id)
}
}
impl Default for BlankNode {
/// Builds a new RDF [blank node](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node) with a unique id
fn default() -> Self {
BlankNode { id: Uuid::new_v4() }
}
}

@ -0,0 +1,140 @@
use model::named_node::NamedNode;
use model::vocab::rdf;
use model::vocab::xsd;
use std::borrow::Cow;
use std::fmt;
use std::option::Option;
use utils::Escaper;
/// A RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal)
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum Literal {
SimpleLiteral(String),
String(String),
LanguageTaggedString { value: String, language: String },
Boolean(bool),
TypedLiteral { value: String, datatype: NamedNode },
}
impl Literal {
/// Builds a RDF [simple literal](https://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal)
pub fn new_simple_literal(value: impl Into<String>) -> Self {
Literal::SimpleLiteral(value.into())
}
/// Builds a 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: impl Into<String>, datatype: impl Into<NamedNode>) -> Self {
//TODO: proper casts
Literal::TypedLiteral {
value: value.into(),
datatype: datatype.into(),
}
}
/// Builds a RDF [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string)
pub fn new_language_tagged_literal(
value: impl Into<String>,
language: impl Into<String>,
) -> Self {
Literal::LanguageTaggedString {
value: value.into(),
language: language.into(),
}
}
/// The literal [lexical form](https://www.w3.org/TR/rdf11-concepts/#dfn-lexical-form)
pub fn value<'a>(&'a self) -> Cow<'a, String> {
match self {
Literal::SimpleLiteral(value) => Cow::Borrowed(value),
Literal::String(value) => Cow::Borrowed(value),
Literal::LanguageTaggedString { value, .. } => Cow::Borrowed(value),
Literal::Boolean(value) => Cow::Owned(value.to_string()),
Literal::TypedLiteral { value, .. } => Cow::Borrowed(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)
pub fn language(&self) -> Option<&str> {
match self {
Literal::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 http://www.w3.org/1999/02/22-rdf-syntax-ns#langString
pub fn datatype(&self) -> &NamedNode {
match self {
Literal::SimpleLiteral(_) => &xsd::STRING,
Literal::String(_) => &xsd::STRING,
Literal::LanguageTaggedString { .. } => &rdf::LANG_STRING,
Literal::Boolean(_) => &xsd::BOOLEAN,
Literal::TypedLiteral { datatype, .. } => datatype,
}
}
pub fn is_plain(&self) -> bool {
match self {
Literal::SimpleLiteral(_) => true,
Literal::LanguageTaggedString { .. } => true,
_ => false,
}
}
}
impl fmt::Display for Literal {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.is_plain() {
self.language()
.map(|lang| write!(f, "\"{}\"@{}", self.value().escape(), lang))
.unwrap_or_else(|| write!(f, "\"{}\"", self.value().escape()))
} else {
write!(f, "\"{}\"^^{}", self.value().escape(), self.datatype())
}
}
}
impl<'a> From<&'a str> for Literal {
fn from(value: &'a str) -> Self {
Literal::String(value.into())
}
}
impl From<String> for Literal {
fn from(value: String) -> Self {
Literal::String(value)
}
}
impl From<bool> for Literal {
fn from(value: bool) -> Self {
Literal::Boolean(value)
}
}
impl From<usize> for Literal {
fn from(value: usize) -> Self {
Literal::TypedLiteral {
value: value.to_string(),
datatype: xsd::INTEGER.clone(),
}
}
}
impl From<f32> for Literal {
fn from(value: f32) -> Self {
Literal::TypedLiteral {
value: value.to_string(),
datatype: xsd::FLOAT.clone(),
}
}
}
impl From<f64> for Literal {
fn from(value: f64) -> Self {
Literal::TypedLiteral {
value: value.to_string(),
datatype: xsd::DOUBLE.clone(),
}
}
}

@ -1,2 +1,17 @@
pub mod data;
///! Implements data structures for https://www.w3.org/TR/rdf11-concepts/
///! Inspired by [RDFjs](http://rdf.js.org/)
mod blank_node;
mod literal;
mod named_node;
mod triple;
pub mod vocab;
pub use model::blank_node::BlankNode;
pub use model::literal::Literal;
pub use model::named_node::NamedNode;
pub use model::triple::NamedOrBlankNode;
pub use model::triple::Quad;
pub use model::triple::QuadLike;
pub use model::triple::Term;
pub use model::triple::Triple;
pub use model::triple::TripleLike;

@ -0,0 +1,57 @@
use std::fmt;
use std::ops::Deref;
use std::str::FromStr;
use std::sync::Arc;
use url::ParseError;
use url::Url;
/// A RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri)
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub struct NamedNode {
iri: Arc<Url>,
}
impl fmt::Display for NamedNode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "<{}>", self.iri)
}
}
impl NamedNode {
/// Builds a RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri)
pub fn new(iri: impl Into<Url>) -> Self {
Self {
iri: Arc::new(iri.into()),
}
}
pub fn value(&self) -> &str {
self.iri.as_str()
}
pub fn url(&self) -> &Url {
&self.iri
}
}
impl Deref for NamedNode {
type Target = Url;
fn deref(&self) -> &Url {
&self.iri
}
}
impl From<Url> for NamedNode {
fn from(url: Url) -> Self {
Self { iri: Arc::new(url) }
}
}
impl FromStr for NamedNode {
type Err = ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(NamedNode::new(Url::parse(s)?))
}
}

@ -1,235 +1,7 @@
use std::borrow::Cow;
///! Implements data structures for https://www.w3.org/TR/rdf11-concepts/
///! Inspired by [RDFjs](http://rdf.js.org/)
use model::blank_node::BlankNode;
use model::literal::Literal;
use model::named_node::NamedNode;
use std::fmt;
use std::ops::Deref;
use std::option::Option;
use std::str::FromStr;
use std::sync::Arc;
use url::ParseError;
use url::Url;
use utils::Escaper;
use uuid::Uuid;
/// A RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri)
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub struct NamedNode {
iri: Arc<Url>,
}
impl NamedNode {
/// Builds a RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri)
pub fn new(iri: impl Into<Url>) -> Self {
Self {
iri: Arc::new(iri.into()),
}
}
pub fn value(&self) -> &str {
self.iri.as_str()
}
pub fn url(&self) -> &Url {
&self.iri
}
}
impl Deref for NamedNode {
type Target = Url;
fn deref(&self) -> &Url {
&self.iri
}
}
impl fmt::Display for NamedNode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "<{}>", self.iri)
}
}
impl FromStr for NamedNode {
type Err = ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(NamedNode::new(Url::parse(s)?))
}
}
/// A RDF [blank node](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node)
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub struct BlankNode {
id: Uuid,
}
impl Deref for BlankNode {
type Target = Uuid;
fn deref(&self) -> &Uuid {
&self.id
}
}
impl fmt::Display for BlankNode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "_:{}", self.id)
}
}
impl Default for BlankNode {
/// Builds a new RDF [blank node](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node) with a unique id
fn default() -> Self {
BlankNode { id: Uuid::new_v4() }
}
}
/// A RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal)
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum Literal {
SimpleLiteral(String),
String(String),
LanguageTaggedString { value: String, language: String },
Boolean(bool),
TypedLiteral { value: String, datatype: NamedNode },
}
lazy_static! {
static ref XSD_BOOLEAN: NamedNode =
NamedNode::from_str("http://www.w3.org/2001/XMLSchema#boolean").unwrap();
static ref XSD_DOUBLE: NamedNode =
NamedNode::from_str("http://www.w3.org/2001/XMLSchema#double").unwrap();
static ref XSD_FLOAT: NamedNode =
NamedNode::from_str("http://www.w3.org/2001/XMLSchema#float").unwrap();
static ref XSD_INTEGER: NamedNode =
NamedNode::from_str("http://www.w3.org/2001/XMLSchema#integer").unwrap();
static ref XSD_STRING: NamedNode =
NamedNode::from_str("http://www.w3.org/2001/XMLSchema#string").unwrap();
static ref RDF_LANG_STRING: NamedNode =
NamedNode::from_str("http://www.w3.org/1999/02/22-rdf-syntax-ns#langString").unwrap();
}
impl Literal {
/// Builds a RDF [simple literal](https://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal)
pub fn new_simple_literal(value: impl Into<String>) -> Self {
Literal::SimpleLiteral(value.into())
}
/// Builds a 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: impl Into<String>, datatype: impl Into<NamedNode>) -> Self {
//TODO: proper casts
Literal::TypedLiteral {
value: value.into(),
datatype: datatype.into(),
}
}
/// Builds a RDF [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string)
pub fn new_language_tagged_literal(
value: impl Into<String>,
language: impl Into<String>,
) -> Self {
Literal::LanguageTaggedString {
value: value.into(),
language: language.into(),
}
}
/// The literal [lexical form](https://www.w3.org/TR/rdf11-concepts/#dfn-lexical-form)
pub fn value<'a>(&'a self) -> Cow<'a, String> {
match self {
Literal::SimpleLiteral(value) => Cow::Borrowed(value),
Literal::String(value) => Cow::Borrowed(value),
Literal::LanguageTaggedString { value, .. } => Cow::Borrowed(value),
Literal::Boolean(value) => Cow::Owned(value.to_string()),
Literal::TypedLiteral { value, .. } => Cow::Borrowed(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)
pub fn language(&self) -> Option<&str> {
match self {
Literal::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 http://www.w3.org/1999/02/22-rdf-syntax-ns#langString
pub fn datatype(&self) -> &NamedNode {
match self {
Literal::SimpleLiteral(_) => &XSD_STRING,
Literal::String(_) => &XSD_STRING,
Literal::LanguageTaggedString { .. } => &RDF_LANG_STRING,
Literal::Boolean(_) => &XSD_BOOLEAN,
Literal::TypedLiteral { datatype, .. } => datatype,
}
}
pub fn is_plain(&self) -> bool {
match self {
Literal::SimpleLiteral(_) => true,
Literal::LanguageTaggedString { .. } => true,
_ => false,
}
}
}
impl fmt::Display for Literal {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.is_plain() {
self.language()
.map(|lang| write!(f, "\"{}\"@{}", self.value().escape(), lang))
.unwrap_or_else(|| write!(f, "\"{}\"", self.value().escape()))
} else {
write!(f, "\"{}\"^^{}", self.value().escape(), self.datatype())
}
}
}
impl<'a> From<&'a str> for Literal {
fn from(value: &'a str) -> Self {
Literal::String(value.into())
}
}
impl From<String> for Literal {
fn from(value: String) -> Self {
Literal::String(value)
}
}
impl From<bool> for Literal {
fn from(value: bool) -> Self {
Literal::Boolean(value)
}
}
impl From<usize> for Literal {
fn from(value: usize) -> Self {
Literal::TypedLiteral {
value: value.to_string(),
datatype: XSD_INTEGER.clone(),
}
}
}
impl From<f32> for Literal {
fn from(value: f32) -> Self {
Literal::TypedLiteral {
value: value.to_string(),
datatype: XSD_FLOAT.clone(),
}
}
}
impl From<f64> for Literal {
fn from(value: f64) -> Self {
Literal::TypedLiteral {
value: value.to_string(),
datatype: XSD_DOUBLE.clone(),
}
}
}
/// 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).
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]

@ -1,7 +1,7 @@
///! Provides ready to use NamedNode for basic RDF vocabularies
pub mod rdf {
use model::data::NamedNode;
use model::named_node::NamedNode;
use std::str::FromStr;
lazy_static! {
@ -23,7 +23,7 @@ pub mod rdf {
}
pub mod rdfs {
use model::data::NamedNode;
use model::named_node::NamedNode;
use std::str::FromStr;
lazy_static! {
@ -34,7 +34,7 @@ pub mod rdfs {
pub mod xsd {
///! NamedNodes for [RDF compatible XSD datatypes](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-compatible-xsd-types)
use model::data::NamedNode;
use model::named_node::NamedNode;
use std::str::FromStr;
lazy_static! {

@ -4,7 +4,7 @@ mod grammar {
include!(concat!(env!("OUT_DIR"), "/ntriples_grammar.rs"));
}
use model::data::*;
use model::*;
use rio::*;
use std::collections::BTreeMap;
use std::io::BufRead;

@ -3,7 +3,7 @@
use std::iter::FromIterator;
use std::char;
use std::str::FromStr;
use model::data::*;
use model::*;
use std::collections::BTreeMap;
#![arguments(bnodes_map: &mut BTreeMap<String, BlankNode>)]

@ -3,7 +3,7 @@
mod grammar {
include!(concat!(env!("OUT_DIR"), "/turtle_grammar.rs"));
use model::data::*;
use model::*;
use rio::*;
use std::collections::BTreeMap;
use std::collections::HashMap;

@ -1,4 +1,4 @@
use model::data::*;
use model::*;
use sparql::model::*;
use std::fmt;
use std::ops::Add;

@ -1,4 +1,4 @@
use model::data::*;
use model::*;
use std::fmt;
use uuid::Uuid;

@ -3,7 +3,7 @@ use std::char;
use std::str::Chars;
mod grammar {
use model::data::*;
use model::*;
use rio::RioError;
use rio::RioResult;
use sparql::ast::*;

@ -1,4 +1,4 @@
use model::data::*;
use model::*;
use std::collections::hash_map::DefaultHasher;
use std::collections::BTreeSet;
use std::collections::HashMap;

@ -1,5 +1,5 @@
use model::data::*;
use model::vocab::rdf;
use model::*;
use std::collections::HashSet;
use std::fmt;
use std::iter::FromIterator;

@ -8,9 +8,9 @@ extern crate url;
use reqwest::Client;
use reqwest::Response;
use rudf::model::data::*;
use rudf::model::vocab::rdf;
use rudf::model::vocab::rdfs;
use rudf::model::*;
use rudf::rio::ntriples::read_ntriples;
use rudf::rio::turtle::read_turtle;
use rudf::rio::RioError;
@ -244,7 +244,7 @@ impl<'a> TestManifest<'a> {
}
pub mod mf {
use rudf::model::data::NamedNode;
use rudf::model::NamedNode;
use std::str::FromStr;
lazy_static! {

Loading…
Cancel
Save