parent
35fe15f796
commit
f75dc6a61d
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,302 @@ |
|||||||
|
//! [In-memory implementation](super::Graph) of [RDF graphs](https://www.w3.org/TR/rdf11-concepts/#dfn-graph).
|
||||||
|
//!
|
||||||
|
//! Usage example:
|
||||||
|
//! ```
|
||||||
|
//! use oxigraph::model::*;
|
||||||
|
//!
|
||||||
|
//! 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(())
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! See also [`Dataset`](super::Dataset) if you want to get support of multiple RDF graphs at the same time.
|
||||||
|
|
||||||
|
use crate::io::GraphFormat; |
||||||
|
use crate::model::dataset::*; |
||||||
|
use crate::model::*; |
||||||
|
use std::io::{BufRead, Write}; |
||||||
|
use std::iter::FromIterator; |
||||||
|
use std::{fmt, io}; |
||||||
|
|
||||||
|
/// An in-memory [RDF graph](https://www.w3.org/TR/rdf11-concepts/#dfn-graph).
|
||||||
|
///
|
||||||
|
/// It can accomodate a fairly large number of triples (in the few millions).
|
||||||
|
/// Beware: it interns the string and does not do any garbage collection yet:
|
||||||
|
/// if you insert and remove a lot of different terms, memory will grow without any reduction.
|
||||||
|
///
|
||||||
|
/// Usage example:
|
||||||
|
/// ```
|
||||||
|
/// use oxigraph::model::*;
|
||||||
|
///
|
||||||
|
/// 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(())
|
||||||
|
/// ```
|
||||||
|
#[derive(Debug, Default)] |
||||||
|
pub struct Graph { |
||||||
|
dataset: Dataset, |
||||||
|
} |
||||||
|
|
||||||
|
impl Graph { |
||||||
|
/// Creates a new graph
|
||||||
|
pub fn new() -> Self { |
||||||
|
Self::default() |
||||||
|
} |
||||||
|
|
||||||
|
fn graph(&self) -> GraphView<'_> { |
||||||
|
self.dataset.graph(GraphNameRef::DefaultGraph) |
||||||
|
} |
||||||
|
|
||||||
|
fn graph_mut(&mut self) -> GraphViewMut<'_> { |
||||||
|
self.dataset.graph_mut(GraphNameRef::DefaultGraph) |
||||||
|
} |
||||||
|
|
||||||
|
/// Returns all the triples contained by the graph
|
||||||
|
pub fn iter(&self) -> Iter<'_> { |
||||||
|
Iter { |
||||||
|
inner: self.graph().iter(), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn triples_for_subject<'a, 'b>( |
||||||
|
&'a self, |
||||||
|
subject: impl Into<NamedOrBlankNodeRef<'b>>, |
||||||
|
) -> impl Iterator<Item = TripleRef<'a>> + 'a { |
||||||
|
self.graph() |
||||||
|
.triples_for_interned_subject(self.dataset.encoded_named_or_blank_node(subject)) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn objects_for_subject_predicate<'a, 'b>( |
||||||
|
&'a self, |
||||||
|
subject: impl Into<NamedOrBlankNodeRef<'b>>, |
||||||
|
predicate: impl Into<NamedNodeRef<'b>>, |
||||||
|
) -> impl Iterator<Item = TermRef<'a>> + 'a { |
||||||
|
self.graph().objects_for_interned_subject_predicate( |
||||||
|
self.dataset.encoded_named_or_blank_node(subject), |
||||||
|
self.dataset.encoded_named_node(predicate), |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn object_for_subject_predicate<'a, 'b>( |
||||||
|
&'a self, |
||||||
|
subject: impl Into<NamedOrBlankNodeRef<'b>>, |
||||||
|
predicate: impl Into<NamedNodeRef<'b>>, |
||||||
|
) -> Option<TermRef<'a>> { |
||||||
|
self.graph() |
||||||
|
.objects_for_subject_predicate(subject, predicate) |
||||||
|
.next() |
||||||
|
} |
||||||
|
|
||||||
|
pub fn predicates_for_subject_object<'a, 'b>( |
||||||
|
&'a self, |
||||||
|
subject: impl Into<NamedOrBlankNodeRef<'b>>, |
||||||
|
object: impl Into<TermRef<'b>>, |
||||||
|
) -> impl Iterator<Item = NamedNodeRef<'a>> + 'a { |
||||||
|
self.graph().predicates_for_interned_subject_object( |
||||||
|
self.dataset.encoded_named_or_blank_node(subject), |
||||||
|
self.dataset.encoded_term(object), |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn triples_for_predicate<'a, 'b>( |
||||||
|
&'a self, |
||||||
|
predicate: impl Into<NamedNodeRef<'b>>, |
||||||
|
) -> impl Iterator<Item = TripleRef<'a>> + 'a { |
||||||
|
self.graph() |
||||||
|
.triples_for_interned_predicate(self.dataset.encoded_named_node(predicate)) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn subjects_for_predicate_object<'a, 'b>( |
||||||
|
&'a self, |
||||||
|
predicate: impl Into<NamedNodeRef<'b>>, |
||||||
|
object: impl Into<TermRef<'b>>, |
||||||
|
) -> impl Iterator<Item = NamedOrBlankNodeRef<'a>> + 'a { |
||||||
|
self.graph().subjects_for_interned_predicate_object( |
||||||
|
self.dataset.encoded_named_node(predicate), |
||||||
|
self.dataset.encoded_term(object), |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn subject_for_predicate_object<'a, 'b>( |
||||||
|
&'a self, |
||||||
|
predicate: impl Into<NamedNodeRef<'b>>, |
||||||
|
object: impl Into<TermRef<'b>>, |
||||||
|
) -> Option<NamedOrBlankNodeRef<'a>> { |
||||||
|
self.graph().subject_for_predicate_object(predicate, object) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn triples_for_object<'a, 'b>( |
||||||
|
&'a self, |
||||||
|
object: impl Into<TermRef<'b>>, |
||||||
|
) -> impl Iterator<Item = TripleRef<'a>> + 'a { |
||||||
|
self.graph() |
||||||
|
.triples_for_interned_object(self.dataset.encoded_term(object)) |
||||||
|
} |
||||||
|
|
||||||
|
/// Checks if the graph contains the given triple
|
||||||
|
pub fn contains<'a>(&self, triple: impl Into<TripleRef<'a>>) -> bool { |
||||||
|
self.graph().contains(triple) |
||||||
|
} |
||||||
|
|
||||||
|
/// Returns the number of triples in this graph
|
||||||
|
pub fn len(&self) -> usize { |
||||||
|
self.dataset.len() |
||||||
|
} |
||||||
|
|
||||||
|
/// Checks if this graph contains a triple
|
||||||
|
pub fn is_empty(&self) -> bool { |
||||||
|
self.dataset.is_empty() |
||||||
|
} |
||||||
|
|
||||||
|
/// Adds a triple to the graph
|
||||||
|
pub fn insert<'a>(&mut self, triple: impl Into<TripleRef<'a>>) -> bool { |
||||||
|
self.graph_mut().insert(triple) |
||||||
|
} |
||||||
|
|
||||||
|
/// Removes a concrete triple from the graph
|
||||||
|
pub fn remove<'a>(&mut self, triple: impl Into<TripleRef<'a>>) -> bool { |
||||||
|
self.graph_mut().remove(triple) |
||||||
|
} |
||||||
|
|
||||||
|
/// Loads a file into the graph.
|
||||||
|
///
|
||||||
|
/// Usage example:
|
||||||
|
/// ```
|
||||||
|
/// use oxigraph::model::*;
|
||||||
|
/// use oxigraph::io::GraphFormat;
|
||||||
|
///
|
||||||
|
/// let mut graph = Graph::new();
|
||||||
|
///
|
||||||
|
/// // insertion
|
||||||
|
/// let file = b"<http://example.com> <http://example.com> <http://example.com> .";
|
||||||
|
/// graph.load(file.as_ref(), GraphFormat::NTriples, None)?;
|
||||||
|
///
|
||||||
|
/// // we inspect the store contents
|
||||||
|
/// let ex = NamedNodeRef::new("http://example.com")?;
|
||||||
|
/// assert!(graph.contains(TripleRef::new(ex, ex, ex)));
|
||||||
|
/// # Result::<_,Box<dyn std::error::Error>>::Ok(())
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Warning: This functions inserts the triples during the parsing.
|
||||||
|
/// If the parsing fails in the middle of the file, the triples read before stay in the graph.
|
||||||
|
///
|
||||||
|
/// Errors related to parameter validation like the base IRI use the [`InvalidInput`](std::io::ErrorKind::InvalidInput) error kind.
|
||||||
|
/// Errors related to a bad syntax in the loaded file use the [`InvalidData`](std::io::ErrorKind::InvalidData) or [`UnexpectedEof`](std::io::ErrorKind::UnexpectedEof) error kinds.
|
||||||
|
pub fn load( |
||||||
|
&mut self, |
||||||
|
reader: impl BufRead, |
||||||
|
format: GraphFormat, |
||||||
|
base_iri: Option<&str>, |
||||||
|
) -> Result<(), io::Error> { |
||||||
|
self.graph_mut().load(reader, format, base_iri) |
||||||
|
} |
||||||
|
|
||||||
|
/// Dumps the graph into a file.
|
||||||
|
///
|
||||||
|
/// Usage example:
|
||||||
|
/// ```
|
||||||
|
/// use oxigraph::io::GraphFormat;
|
||||||
|
/// use oxigraph::model::Graph;
|
||||||
|
///
|
||||||
|
/// let file = "<http://example.com> <http://example.com> <http://example.com> .\n".as_bytes();
|
||||||
|
///
|
||||||
|
/// let mut store = Graph::new();
|
||||||
|
/// store.load(file, GraphFormat::NTriples,None)?;
|
||||||
|
///
|
||||||
|
/// let mut buffer = Vec::new();
|
||||||
|
/// store.dump(&mut buffer, GraphFormat::NTriples)?;
|
||||||
|
/// assert_eq!(file, buffer.as_slice());
|
||||||
|
/// # Result::<_,Box<dyn std::error::Error>>::Ok(())
|
||||||
|
/// ```
|
||||||
|
pub fn dump(&self, writer: impl Write, format: GraphFormat) -> Result<(), io::Error> { |
||||||
|
self.graph().dump(writer, format) |
||||||
|
} |
||||||
|
|
||||||
|
/// Applies on the graph the canonicalization process described in
|
||||||
|
/// [Canonical Forms for Isomorphic and Equivalent RDF Graphs: Algorithms for Leaning and Labelling Blank Nodes, Aidan Hogan, 2017](http://aidanhogan.com/docs/rdf-canonicalisation.pdf)
|
||||||
|
///
|
||||||
|
/// Warning: This implementation worst-case complexity is in O(b!) with b the number of blank nodes in the input graphs.
|
||||||
|
pub fn canonicalize(&mut self) { |
||||||
|
self.dataset.canonicalize() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl PartialEq for Graph { |
||||||
|
fn eq(&self, other: &Self) -> bool { |
||||||
|
self.dataset == other.dataset |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl Eq for Graph {} |
||||||
|
|
||||||
|
impl<'a> IntoIterator for &'a Graph { |
||||||
|
type Item = TripleRef<'a>; |
||||||
|
type IntoIter = Iter<'a>; |
||||||
|
|
||||||
|
fn into_iter(self) -> Iter<'a> { |
||||||
|
self.iter() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl FromIterator<Triple> for Graph { |
||||||
|
fn from_iter<I: IntoIterator<Item = Triple>>(iter: I) -> Self { |
||||||
|
let mut g = Graph::new(); |
||||||
|
g.extend(iter); |
||||||
|
g |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl<'a, T: Into<TripleRef<'a>>> FromIterator<T> for Graph { |
||||||
|
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self { |
||||||
|
let mut g = Graph::new(); |
||||||
|
g.extend(iter); |
||||||
|
g |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl Extend<Triple> for Graph { |
||||||
|
fn extend<I: IntoIterator<Item = Triple>>(&mut self, iter: I) { |
||||||
|
self.graph_mut().extend(iter) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl<'a, T: Into<TripleRef<'a>>> Extend<T> for Graph { |
||||||
|
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) { |
||||||
|
self.graph_mut().extend(iter) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl fmt::Display for Graph { |
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
||||||
|
self.graph().fmt(f) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// Iterator returned by [`Graph::iter`]
|
||||||
|
pub struct Iter<'a> { |
||||||
|
inner: GraphViewIter<'a>, |
||||||
|
} |
||||||
|
|
||||||
|
impl<'a> Iterator for Iter<'a> { |
||||||
|
type Item = TripleRef<'a>; |
||||||
|
|
||||||
|
fn next(&mut self) -> Option<TripleRef<'a>> { |
||||||
|
self.inner.next() |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,344 @@ |
|||||||
|
//! Interning of RDF elements using Rodeo
|
||||||
|
|
||||||
|
use crate::model::*; |
||||||
|
use lasso::{Key, Rodeo, Spur}; |
||||||
|
use std::convert::TryInto; |
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash)] |
||||||
|
pub struct InternedNamedNode { |
||||||
|
id: Spur, |
||||||
|
} |
||||||
|
|
||||||
|
impl InternedNamedNode { |
||||||
|
pub fn encoded_into(named_node: NamedNodeRef<'_>, interner: &mut Rodeo) -> Self { |
||||||
|
Self { |
||||||
|
id: interner.get_or_intern(named_node.as_str()), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn encoded_from(named_node: NamedNodeRef<'_>, interner: &Rodeo) -> Option<Self> { |
||||||
|
Some(Self { |
||||||
|
id: interner.get(named_node.as_str())?, |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn decode_from<'a>(&self, interner: &'a Rodeo) -> NamedNodeRef<'a> { |
||||||
|
NamedNodeRef::new_unchecked(interner.resolve(&self.id)) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn first() -> Self { |
||||||
|
Self { id: fist_spur() } |
||||||
|
} |
||||||
|
|
||||||
|
pub fn next(&self) -> Self { |
||||||
|
Self { |
||||||
|
id: next_spur(self.id), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn impossible() -> Self { |
||||||
|
Self { |
||||||
|
id: impossible_spur(), |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash)] |
||||||
|
pub struct InternedBlankNode { |
||||||
|
id: Spur, |
||||||
|
} |
||||||
|
|
||||||
|
impl InternedBlankNode { |
||||||
|
pub fn encoded_into(blank_node: BlankNodeRef<'_>, interner: &mut Rodeo) -> Self { |
||||||
|
Self { |
||||||
|
id: interner.get_or_intern(blank_node.as_str()), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn encoded_from(blank_node: BlankNodeRef<'_>, interner: &Rodeo) -> Option<Self> { |
||||||
|
Some(Self { |
||||||
|
id: interner.get(blank_node.as_str())?, |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn decode_from<'a>(&self, interner: &'a Rodeo) -> BlankNodeRef<'a> { |
||||||
|
BlankNodeRef::new_unchecked(interner.resolve(&self.id)) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn next(&self) -> Self { |
||||||
|
Self { |
||||||
|
id: next_spur(self.id), |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash)] |
||||||
|
pub enum InternedLiteral { |
||||||
|
String { |
||||||
|
value_id: Spur, |
||||||
|
}, |
||||||
|
LanguageTaggedString { |
||||||
|
value_id: Spur, |
||||||
|
language_id: Spur, |
||||||
|
}, |
||||||
|
TypedLiteral { |
||||||
|
value_id: Spur, |
||||||
|
datatype: InternedNamedNode, |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
impl InternedLiteral { |
||||||
|
pub fn encoded_into(literal: LiteralRef<'_>, interner: &mut Rodeo) -> Self { |
||||||
|
let value_id = interner.get_or_intern(literal.value()); |
||||||
|
if literal.is_plain() { |
||||||
|
if let Some(language) = literal.language() { |
||||||
|
Self::LanguageTaggedString { |
||||||
|
value_id, |
||||||
|
language_id: interner.get_or_intern(language), |
||||||
|
} |
||||||
|
} else { |
||||||
|
Self::String { value_id } |
||||||
|
} |
||||||
|
} else { |
||||||
|
Self::TypedLiteral { |
||||||
|
value_id, |
||||||
|
datatype: InternedNamedNode::encoded_into(literal.datatype(), interner), |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn encoded_from(literal: LiteralRef<'_>, interner: &Rodeo) -> Option<Self> { |
||||||
|
let value_id = interner.get(literal.value())?; |
||||||
|
Some(if literal.is_plain() { |
||||||
|
if let Some(language) = literal.language() { |
||||||
|
Self::LanguageTaggedString { |
||||||
|
value_id, |
||||||
|
language_id: interner.get(language)?, |
||||||
|
} |
||||||
|
} else { |
||||||
|
Self::String { value_id } |
||||||
|
} |
||||||
|
} else { |
||||||
|
Self::TypedLiteral { |
||||||
|
value_id, |
||||||
|
datatype: InternedNamedNode::encoded_from(literal.datatype(), interner)?, |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn decode_from<'a>(&self, interner: &'a Rodeo) -> LiteralRef<'a> { |
||||||
|
match self { |
||||||
|
InternedLiteral::String { value_id } => { |
||||||
|
LiteralRef::new_simple_literal(interner.resolve(value_id)) |
||||||
|
} |
||||||
|
InternedLiteral::LanguageTaggedString { |
||||||
|
value_id, |
||||||
|
language_id, |
||||||
|
} => LiteralRef::new_language_tagged_literal_unchecked( |
||||||
|
interner.resolve(value_id), |
||||||
|
interner.resolve(language_id), |
||||||
|
), |
||||||
|
InternedLiteral::TypedLiteral { value_id, datatype } => LiteralRef::new_typed_literal( |
||||||
|
interner.resolve(value_id), |
||||||
|
datatype.decode_from(interner), |
||||||
|
), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn next(&self) -> Self { |
||||||
|
match self { |
||||||
|
Self::String { value_id } => Self::String { |
||||||
|
value_id: next_spur(*value_id), |
||||||
|
}, |
||||||
|
Self::LanguageTaggedString { |
||||||
|
value_id, |
||||||
|
language_id, |
||||||
|
} => Self::LanguageTaggedString { |
||||||
|
value_id: *value_id, |
||||||
|
language_id: next_spur(*language_id), |
||||||
|
}, |
||||||
|
Self::TypedLiteral { value_id, datatype } => Self::TypedLiteral { |
||||||
|
value_id: *value_id, |
||||||
|
datatype: datatype.next(), |
||||||
|
}, |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash)] |
||||||
|
pub enum InternedNamedOrBlankNode { |
||||||
|
NamedNode(InternedNamedNode), |
||||||
|
BlankNode(InternedBlankNode), |
||||||
|
} |
||||||
|
|
||||||
|
impl InternedNamedOrBlankNode { |
||||||
|
pub fn encoded_into(node: NamedOrBlankNodeRef<'_>, interner: &mut Rodeo) -> Self { |
||||||
|
match node { |
||||||
|
NamedOrBlankNodeRef::NamedNode(node) => { |
||||||
|
Self::NamedNode(InternedNamedNode::encoded_into(node, interner)) |
||||||
|
} |
||||||
|
NamedOrBlankNodeRef::BlankNode(node) => { |
||||||
|
Self::BlankNode(InternedBlankNode::encoded_into(node, interner)) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn encoded_from(node: NamedOrBlankNodeRef<'_>, interner: &Rodeo) -> Option<Self> { |
||||||
|
Some(match node { |
||||||
|
NamedOrBlankNodeRef::NamedNode(node) => { |
||||||
|
Self::NamedNode(InternedNamedNode::encoded_from(node, interner)?) |
||||||
|
} |
||||||
|
NamedOrBlankNodeRef::BlankNode(node) => { |
||||||
|
Self::BlankNode(InternedBlankNode::encoded_from(node, interner)?) |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn decode_from<'a>(&self, interner: &'a Rodeo) -> NamedOrBlankNodeRef<'a> { |
||||||
|
match self { |
||||||
|
Self::NamedNode(node) => NamedOrBlankNodeRef::NamedNode(node.decode_from(interner)), |
||||||
|
Self::BlankNode(node) => NamedOrBlankNodeRef::BlankNode(node.decode_from(interner)), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn first() -> Self { |
||||||
|
Self::NamedNode(InternedNamedNode::first()) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn next(&self) -> Self { |
||||||
|
match self { |
||||||
|
Self::NamedNode(node) => Self::NamedNode(node.next()), |
||||||
|
Self::BlankNode(node) => Self::BlankNode(node.next()), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn impossible() -> Self { |
||||||
|
Self::NamedNode(InternedNamedNode::impossible()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash)] |
||||||
|
pub enum InternedGraphName { |
||||||
|
DefaultGraph, |
||||||
|
NamedNode(InternedNamedNode), |
||||||
|
BlankNode(InternedBlankNode), |
||||||
|
} |
||||||
|
|
||||||
|
impl InternedGraphName { |
||||||
|
pub fn encoded_into(node: GraphNameRef<'_>, interner: &mut Rodeo) -> Self { |
||||||
|
match node { |
||||||
|
GraphNameRef::DefaultGraph => Self::DefaultGraph, |
||||||
|
GraphNameRef::NamedNode(node) => { |
||||||
|
Self::NamedNode(InternedNamedNode::encoded_into(node, interner)) |
||||||
|
} |
||||||
|
GraphNameRef::BlankNode(node) => { |
||||||
|
Self::BlankNode(InternedBlankNode::encoded_into(node, interner)) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn encoded_from(node: GraphNameRef<'_>, interner: &Rodeo) -> Option<Self> { |
||||||
|
Some(match node { |
||||||
|
GraphNameRef::DefaultGraph => Self::DefaultGraph, |
||||||
|
GraphNameRef::NamedNode(node) => { |
||||||
|
Self::NamedNode(InternedNamedNode::encoded_from(node, interner)?) |
||||||
|
} |
||||||
|
GraphNameRef::BlankNode(node) => { |
||||||
|
Self::BlankNode(InternedBlankNode::encoded_from(node, interner)?) |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn decode_from<'a>(&self, interner: &'a Rodeo) -> GraphNameRef<'a> { |
||||||
|
match self { |
||||||
|
Self::DefaultGraph => GraphNameRef::DefaultGraph, |
||||||
|
Self::NamedNode(node) => GraphNameRef::NamedNode(node.decode_from(interner)), |
||||||
|
Self::BlankNode(node) => GraphNameRef::BlankNode(node.decode_from(interner)), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn first() -> Self { |
||||||
|
Self::DefaultGraph |
||||||
|
} |
||||||
|
|
||||||
|
pub fn next(&self) -> Self { |
||||||
|
match self { |
||||||
|
Self::DefaultGraph => Self::NamedNode(InternedNamedNode::first()), |
||||||
|
Self::NamedNode(node) => Self::NamedNode(node.next()), |
||||||
|
Self::BlankNode(node) => Self::BlankNode(node.next()), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn impossible() -> Self { |
||||||
|
Self::NamedNode(InternedNamedNode::impossible()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash)] |
||||||
|
pub enum InternedTerm { |
||||||
|
NamedNode(InternedNamedNode), |
||||||
|
BlankNode(InternedBlankNode), |
||||||
|
Literal(InternedLiteral), |
||||||
|
} |
||||||
|
|
||||||
|
impl InternedTerm { |
||||||
|
pub fn encoded_into(term: TermRef<'_>, interner: &mut Rodeo) -> Self { |
||||||
|
match term { |
||||||
|
TermRef::NamedNode(term) => { |
||||||
|
Self::NamedNode(InternedNamedNode::encoded_into(term, interner)) |
||||||
|
} |
||||||
|
TermRef::BlankNode(term) => { |
||||||
|
Self::BlankNode(InternedBlankNode::encoded_into(term, interner)) |
||||||
|
} |
||||||
|
TermRef::Literal(term) => Self::Literal(InternedLiteral::encoded_into(term, interner)), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn encoded_from(term: TermRef<'_>, interner: &Rodeo) -> Option<Self> { |
||||||
|
Some(match term { |
||||||
|
TermRef::NamedNode(term) => { |
||||||
|
Self::NamedNode(InternedNamedNode::encoded_from(term, interner)?) |
||||||
|
} |
||||||
|
TermRef::BlankNode(term) => { |
||||||
|
Self::BlankNode(InternedBlankNode::encoded_from(term, interner)?) |
||||||
|
} |
||||||
|
TermRef::Literal(term) => Self::Literal(InternedLiteral::encoded_from(term, interner)?), |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn decode_from<'a>(&self, interner: &'a Rodeo) -> TermRef<'a> { |
||||||
|
match self { |
||||||
|
Self::NamedNode(term) => TermRef::NamedNode(term.decode_from(interner)), |
||||||
|
Self::BlankNode(term) => TermRef::BlankNode(term.decode_from(interner)), |
||||||
|
Self::Literal(term) => TermRef::Literal(term.decode_from(interner)), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn first() -> Self { |
||||||
|
Self::NamedNode(InternedNamedNode::first()) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn next(&self) -> Self { |
||||||
|
match self { |
||||||
|
Self::NamedNode(node) => Self::NamedNode(node.next()), |
||||||
|
Self::BlankNode(node) => Self::BlankNode(node.next()), |
||||||
|
Self::Literal(node) => Self::Literal(node.next()), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn impossible() -> Self { |
||||||
|
Self::NamedNode(InternedNamedNode::impossible()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fn fist_spur() -> Spur { |
||||||
|
Spur::try_from_usize(0).unwrap() |
||||||
|
} |
||||||
|
|
||||||
|
fn next_spur(value: Spur) -> Spur { |
||||||
|
Spur::try_from_usize(value.into_usize() + 1).unwrap() |
||||||
|
} |
||||||
|
|
||||||
|
fn impossible_spur() -> Spur { |
||||||
|
Spur::try_from_usize((u32::max_value() - 10).try_into().unwrap()).unwrap() |
||||||
|
} |
Loading…
Reference in new issue