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