Allows to reuse it in other crates like spargebrapull/190/head
parent
4337349aad
commit
f5545f1948
@ -0,0 +1,24 @@ |
||||
[package] |
||||
name = "oxrdf" |
||||
version = "0.1.0" |
||||
authors = ["Tpt <thomas@pellissier-tanon.fr>"] |
||||
license = "MIT OR Apache-2.0" |
||||
readme = "README.md" |
||||
keywords = ["RDF"] |
||||
repository = "https://github.com/oxigraph/oxigraph/tree/master/lib/oxrdf" |
||||
homepage = "https://oxigraph.org/" |
||||
description = """ |
||||
A library providing basic data structures related to RDF |
||||
""" |
||||
edition = "2021" |
||||
|
||||
[dependencies] |
||||
rand = "0.8" |
||||
oxilangtag = "0.1" |
||||
oxiri = "0.1" |
||||
rio_api = "0.6" |
||||
lasso = {version="0.6", features=["multi-threaded", "inline-more"]} |
||||
sophia_api = { version = "0.7", optional = true } |
||||
|
||||
[package.metadata.docs.rs] |
||||
all-features = true |
@ -0,0 +1,47 @@ |
||||
OxRDF |
||||
===== |
||||
|
||||
[![Latest Version](https://img.shields.io/crates/v/oxrdf.svg)](https://crates.io/crates/oxrdf) |
||||
[![Released API docs](https://docs.rs/oxrdf/badge.svg)](https://docs.rs/oxrdf) |
||||
[![Crates.io downloads](https://img.shields.io/crates/d/oxrdf)](https://crates.io/crates/oxrdf) |
||||
[![actions status](https://github.com/oxigraph/oxigraph/workflows/build/badge.svg)](https://github.com/oxigraph/oxigraph/actions) |
||||
[![Gitter](https://badges.gitter.im/oxigraph/community.svg)](https://gitter.im/oxigraph/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) |
||||
|
||||
OxRDF is a simple library providing datastructures encoding [RDF 1.1 concepts](https://www.w3.org/TR/rdf11-concepts/). |
||||
|
||||
This crate is intended to be a basic building block of other crates like [Oxigraph](https://crates.io/crates/oxigraph) or [Spargebra](https://crates.io/crates/spargebra). |
||||
|
||||
Inspired by [RDF/JS](https://rdf.js.org/data-model-spec/) and [Apache Commons RDF](http://commons.apache.org/proper/commons-rdf/). |
||||
|
||||
Usage example: |
||||
|
||||
```rust |
||||
use oxrdf::*; |
||||
|
||||
let mut graph = Graph::default(); |
||||
|
||||
// insertion |
||||
let ex = NamedNodeRef::new("http://example.com")?; |
||||
let triple = TripleRef::new(ex, ex, ex); |
||||
graph.insert(triple); |
||||
|
||||
// simple filter |
||||
let results: Vec<_> = graph.triples_for_subject(ex).collect(); |
||||
assert_eq!(vec![triple], results); |
||||
``` |
||||
|
||||
## License |
||||
|
||||
This project is licensed under either of |
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](../LICENSE-APACHE) or |
||||
http://www.apache.org/licenses/LICENSE-2.0) |
||||
* MIT license ([LICENSE-MIT](../LICENSE-MIT) or |
||||
http://opensource.org/licenses/MIT) |
||||
|
||||
at your option. |
||||
|
||||
|
||||
### Contribution |
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Futures by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. |
@ -1,6 +1,6 @@ |
||||
//! Interning of RDF elements using Rodeo
|
||||
|
||||
use crate::model::*; |
||||
use crate::*; |
||||
use lasso::{Key, Rodeo, Spur}; |
||||
use std::collections::HashMap; |
||||
|
@ -0,0 +1,51 @@ |
||||
//! OxRDF is a simple library providing datastructures encoding [RDF 1.1 concepts](https://www.w3.org/TR/rdf11-concepts/).
|
||||
//!
|
||||
//! This crate is intended to be a basic building block of other crates like [Oxigraph](https://crates.io/crates/oxigraph) or [Spargebra](https://crates.io/crates/spargebra).
|
||||
//!
|
||||
//! Inspired by [RDF/JS](https://rdf.js.org/data-model-spec/) and [Apache Commons RDF](http://commons.apache.org/proper/commons-rdf/).
|
||||
//!
|
||||
//! Usage example:
|
||||
//!
|
||||
//! Usage example:
|
||||
//! ```
|
||||
//! use oxrdf::*;
|
||||
//!
|
||||
//! let mut graph = Graph::default();
|
||||
//!
|
||||
//! // insertion
|
||||
//! let ex = NamedNodeRef::new("http://example.com")?;
|
||||
//! let triple = TripleRef::new(ex, ex, ex);
|
||||
//! graph.insert(triple);
|
||||
//!
|
||||
//! // simple filter
|
||||
//! let results: Vec<_> = graph.triples_for_subject(ex).collect();
|
||||
//! assert_eq!(vec![triple], results);
|
||||
//! # Result::<_,Box<dyn std::error::Error>>::Ok(())
|
||||
//! ```
|
||||
|
||||
mod blank_node; |
||||
pub mod dataset; |
||||
pub mod graph; |
||||
mod interning; |
||||
mod literal; |
||||
mod named_node; |
||||
mod parser; |
||||
#[cfg(feature = "sophia_api")] |
||||
mod sophia; |
||||
mod triple; |
||||
mod variable; |
||||
pub mod vocab; |
||||
|
||||
pub use crate::blank_node::{BlankNode, BlankNodeIdParseError, BlankNodeRef}; |
||||
pub use crate::dataset::Dataset; |
||||
pub use crate::graph::Graph; |
||||
pub use crate::literal::{Literal, LiteralRef}; |
||||
pub use crate::named_node::{NamedNode, NamedNodeRef}; |
||||
pub use crate::parser::TermParseError; |
||||
pub use crate::triple::{ |
||||
GraphName, GraphNameRef, NamedOrBlankNode, NamedOrBlankNodeRef, Quad, QuadRef, Subject, |
||||
SubjectRef, Term, TermRef, Triple, TripleRef, |
||||
}; |
||||
pub use crate::variable::{Variable, VariableNameParseError}; |
||||
pub use oxilangtag::LanguageTagParseError; |
||||
pub use oxiri::IriParseError; |
@ -1,6 +1,6 @@ |
||||
//! This crate provides implementation of [Sophia](https://docs.rs/sophia/) traits for the `model` module.
|
||||
|
||||
use crate::model::*; |
||||
use crate::*; |
||||
use sophia_api::term::*; |
||||
use std::fmt; |
||||
|
@ -1,7 +1,7 @@ |
||||
use crate::model::blank_node::BlankNode; |
||||
use crate::model::literal::Literal; |
||||
use crate::model::named_node::NamedNode; |
||||
use crate::model::{BlankNodeRef, LiteralRef, NamedNodeRef}; |
||||
use crate::blank_node::BlankNode; |
||||
use crate::literal::Literal; |
||||
use crate::named_node::NamedNode; |
||||
use crate::{BlankNodeRef, LiteralRef, NamedNodeRef}; |
||||
use std::fmt; |
||||
use std::sync::Arc; |
||||
|
@ -0,0 +1,121 @@ |
||||
use std::error::Error; |
||||
use std::fmt; |
||||
|
||||
/// A [SPARQL query](https://www.w3.org/TR/sparql11-query/) variable.
|
||||
///
|
||||
/// ```
|
||||
/// use oxrdf::{Variable, VariableNameParseError};
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// "?foo",
|
||||
/// Variable::new("foo")?.to_string()
|
||||
/// );
|
||||
/// # Result::<_,VariableNameParseError>::Ok(())
|
||||
/// ```
|
||||
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)] |
||||
pub struct Variable { |
||||
name: String, |
||||
} |
||||
|
||||
impl Variable { |
||||
/// Creates a variable name from a unique identifier.
|
||||
///
|
||||
/// The variable identifier must be valid according to the SPARQL grammar.
|
||||
pub fn new(name: impl Into<String>) -> Result<Self, VariableNameParseError> { |
||||
let name = name.into(); |
||||
validate_variable_identifier(&name)?; |
||||
Ok(Self::new_unchecked(name)) |
||||
} |
||||
|
||||
/// Creates a variable name from a unique identifier without validation.
|
||||
///
|
||||
/// It is the caller's responsibility to ensure that `id` is a valid blank node identifier
|
||||
/// according to the SPARQL grammar.
|
||||
///
|
||||
/// [`Variable::new()`] is a safe version of this constructor and should be used for untrusted data.
|
||||
#[inline] |
||||
pub fn new_unchecked(name: impl Into<String>) -> Self { |
||||
Self { name: name.into() } |
||||
} |
||||
|
||||
#[inline] |
||||
pub fn as_str(&self) -> &str { |
||||
&self.name |
||||
} |
||||
|
||||
#[inline] |
||||
pub fn into_string(self) -> String { |
||||
self.name |
||||
} |
||||
} |
||||
|
||||
impl fmt::Display for Variable { |
||||
#[inline] |
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
||||
write!(f, "?{}", self.name) |
||||
} |
||||
} |
||||
|
||||
fn validate_variable_identifier(id: &str) -> Result<(), VariableNameParseError> { |
||||
let mut chars = id.chars(); |
||||
let front = chars.next().ok_or(VariableNameParseError {})?; |
||||
match front { |
||||
'0'..='9' |
||||
| '_' |
||||
| ':' |
||||
| 'A'..='Z' |
||||
| 'a'..='z' |
||||
| '\u{00C0}'..='\u{00D6}' |
||||
| '\u{00D8}'..='\u{00F6}' |
||||
| '\u{00F8}'..='\u{02FF}' |
||||
| '\u{0370}'..='\u{037D}' |
||||
| '\u{037F}'..='\u{1FFF}' |
||||
| '\u{200C}'..='\u{200D}' |
||||
| '\u{2070}'..='\u{218F}' |
||||
| '\u{2C00}'..='\u{2FEF}' |
||||
| '\u{3001}'..='\u{D7FF}' |
||||
| '\u{F900}'..='\u{FDCF}' |
||||
| '\u{FDF0}'..='\u{FFFD}' |
||||
| '\u{10000}'..='\u{EFFFF}' => (), |
||||
_ => return Err(VariableNameParseError {}), |
||||
} |
||||
for c in chars { |
||||
match c { |
||||
'0'..='9' |
||||
| '\u{00B7}' |
||||
| '\u{00300}'..='\u{036F}' |
||||
| '\u{203F}'..='\u{2040}' |
||||
| '_' |
||||
| 'A'..='Z' |
||||
| 'a'..='z' |
||||
| '\u{00C0}'..='\u{00D6}' |
||||
| '\u{00D8}'..='\u{00F6}' |
||||
| '\u{00F8}'..='\u{02FF}' |
||||
| '\u{0370}'..='\u{037D}' |
||||
| '\u{037F}'..='\u{1FFF}' |
||||
| '\u{200C}'..='\u{200D}' |
||||
| '\u{2070}'..='\u{218F}' |
||||
| '\u{2C00}'..='\u{2FEF}' |
||||
| '\u{3001}'..='\u{D7FF}' |
||||
| '\u{F900}'..='\u{FDCF}' |
||||
| '\u{FDF0}'..='\u{FFFD}' |
||||
| '\u{10000}'..='\u{EFFFF}' => (), |
||||
_ => return Err(VariableNameParseError {}), |
||||
} |
||||
} |
||||
Ok(()) |
||||
} |
||||
|
||||
/// An error raised during [`Variable`] name validation.
|
||||
#[allow(missing_copy_implementations)] |
||||
#[derive(Debug)] |
||||
pub struct VariableNameParseError {} |
||||
|
||||
impl fmt::Display for VariableNameParseError { |
||||
#[inline] |
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
||||
write!(f, "The variable name is invalid") |
||||
} |
||||
} |
||||
|
||||
impl Error for VariableNameParseError {} |
@ -0,0 +1,108 @@ |
||||
//! Implements data structures for [RDF 1.1 Concepts](https://www.w3.org/TR/rdf11-concepts/) using [Oxrdf](https://crates.io/crates/oxrdf).
|
||||
|
||||
use crate::xsd::*; |
||||
use oxrdf::vocab::xsd; |
||||
pub use oxrdf::{ |
||||
dataset, graph, vocab, BlankNode, BlankNodeIdParseError, BlankNodeRef, Dataset, Graph, |
||||
GraphName, GraphNameRef, IriParseError, LanguageTagParseError, Literal, LiteralRef, NamedNode, |
||||
NamedNodeRef, NamedOrBlankNode, NamedOrBlankNodeRef, Quad, QuadRef, Subject, SubjectRef, Term, |
||||
TermParseError, TermRef, Triple, TripleRef, |
||||
}; |
||||
|
||||
impl From<Float> for Literal { |
||||
#[inline] |
||||
fn from(value: Float) -> Self { |
||||
Self::new_typed_literal(value.to_string(), xsd::FLOAT) |
||||
} |
||||
} |
||||
|
||||
impl From<Double> for Literal { |
||||
#[inline] |
||||
fn from(value: Double) -> Self { |
||||
Self::new_typed_literal(value.to_string(), xsd::DOUBLE) |
||||
} |
||||
} |
||||
|
||||
impl From<Decimal> for Literal { |
||||
#[inline] |
||||
fn from(value: Decimal) -> Self { |
||||
Self::new_typed_literal(value.to_string(), xsd::DECIMAL) |
||||
} |
||||
} |
||||
|
||||
impl From<DateTime> for Literal { |
||||
#[inline] |
||||
fn from(value: DateTime) -> Self { |
||||
Self::new_typed_literal(value.to_string(), xsd::DATE_TIME) |
||||
} |
||||
} |
||||
|
||||
impl From<Time> for Literal { |
||||
#[inline] |
||||
fn from(value: Time) -> Self { |
||||
Self::new_typed_literal(value.to_string(), xsd::TIME) |
||||
} |
||||
} |
||||
|
||||
impl From<Date> for Literal { |
||||
#[inline] |
||||
fn from(value: Date) -> Self { |
||||
Self::new_typed_literal(value.to_string(), xsd::DATE) |
||||
} |
||||
} |
||||
|
||||
impl From<GYearMonth> for Literal { |
||||
#[inline] |
||||
fn from(value: GYearMonth) -> Self { |
||||
Self::new_typed_literal(value.to_string(), xsd::G_YEAR_MONTH) |
||||
} |
||||
} |
||||
|
||||
impl From<GYear> for Literal { |
||||
#[inline] |
||||
fn from(value: GYear) -> Self { |
||||
Self::new_typed_literal(value.to_string(), xsd::G_YEAR) |
||||
} |
||||
} |
||||
|
||||
impl From<GMonthDay> for Literal { |
||||
#[inline] |
||||
fn from(value: GMonthDay) -> Self { |
||||
Self::new_typed_literal(value.to_string(), xsd::G_MONTH_DAY) |
||||
} |
||||
} |
||||
|
||||
impl From<GMonth> for Literal { |
||||
#[inline] |
||||
fn from(value: GMonth) -> Self { |
||||
Self::new_typed_literal(value.to_string(), xsd::G_MONTH) |
||||
} |
||||
} |
||||
|
||||
impl From<GDay> for Literal { |
||||
#[inline] |
||||
fn from(value: GDay) -> Self { |
||||
Self::new_typed_literal(value.to_string(), xsd::G_DAY) |
||||
} |
||||
} |
||||
|
||||
impl From<Duration> for Literal { |
||||
#[inline] |
||||
fn from(value: Duration) -> Self { |
||||
Self::new_typed_literal(value.to_string(), xsd::DURATION) |
||||
} |
||||
} |
||||
|
||||
impl From<YearMonthDuration> for Literal { |
||||
#[inline] |
||||
fn from(value: YearMonthDuration) -> Self { |
||||
Self::new_typed_literal(value.to_string(), xsd::YEAR_MONTH_DURATION) |
||||
} |
||||
} |
||||
|
||||
impl From<DayTimeDuration> for Literal { |
||||
#[inline] |
||||
fn from(value: DayTimeDuration) -> Self { |
||||
Self::new_typed_literal(value.to_string(), xsd::DAY_TIME_DURATION) |
||||
} |
||||
} |
@ -1,28 +0,0 @@ |
||||
//! Implements data structures for [RDF 1.1 Concepts](https://www.w3.org/TR/rdf11-concepts/).
|
||||
//!
|
||||
//! Inspired by [RDF/JS](https://rdf.js.org/data-model-spec/) and [Apache Commons RDF](http://commons.apache.org/proper/commons-rdf/)
|
||||
|
||||
mod blank_node; |
||||
pub mod dataset; |
||||
pub mod graph; |
||||
mod interning; |
||||
mod literal; |
||||
mod named_node; |
||||
mod parser; |
||||
#[cfg(feature = "sophia")] |
||||
mod sophia; |
||||
mod triple; |
||||
pub mod vocab; |
||||
|
||||
pub use self::blank_node::{BlankNode, BlankNodeIdParseError, BlankNodeRef}; |
||||
pub use self::dataset::Dataset; |
||||
pub use self::graph::Graph; |
||||
pub use self::literal::{Literal, LiteralRef}; |
||||
pub use self::named_node::{NamedNode, NamedNodeRef}; |
||||
pub use self::parser::TermParseError; |
||||
pub use self::triple::{ |
||||
GraphName, GraphNameRef, NamedOrBlankNode, NamedOrBlankNodeRef, Quad, QuadRef, Subject, |
||||
SubjectRef, Term, TermRef, Triple, TripleRef, |
||||
}; |
||||
pub use oxilangtag::LanguageTagParseError; |
||||
pub use oxiri::IriParseError; |
Loading…
Reference in new issue