use crate::statement::{ObjectNodeRef, StatementRef, SubjectNodeRef};
use rdftk_iri::IRIRef;
use std::cell::RefCell;
use std::collections::HashSet;
use std::fmt::{Display, Formatter};
use std::rc::Rc;
use std::sync::Arc;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum GraphIndex {
#[allow(missing_docs)]
Subject,
#[allow(missing_docs)]
Predicate,
#[allow(missing_docs)]
Object,
#[allow(missing_docs)]
SubjectPredicate,
#[allow(missing_docs)]
SubjectPredicateObject,
#[allow(missing_docs)]
SubjectObject,
#[allow(missing_docs)]
PredicateObject,
}
pub trait GraphFactory {
fn new_graph(&self) -> GraphRef;
fn graph_from(
&self,
statements: &[StatementRef],
prefix_mappings: Option<PrefixMappingRef>,
) -> GraphRef {
let graph = self.new_graph();
{
let mut graph = graph.borrow_mut();
for st in statements {
graph.insert(st.clone());
}
if let Some(prefix_mappings) = prefix_mappings {
graph.set_prefix_mappings(prefix_mappings)
}
}
graph
}
}
pub type GraphFactoryRef = Arc<dyn GraphFactory>;
pub type GraphRef = Rc<RefCell<dyn Graph>>;
pub trait Graph {
fn is_empty(&self) -> bool;
fn len(&self) -> usize;
fn contains_subject(&self, subject: &SubjectNodeRef) -> bool;
fn contains_individual(&self, subject: &IRIRef) -> bool;
fn contains(&self, statement: &StatementRef) -> bool {
!self
.matches(
Some(statement.subject()),
Some(statement.predicate()),
Some(statement.object()),
)
.is_empty()
}
fn contains_all(
&self,
subject: &SubjectNodeRef,
predicate: &IRIRef,
object: &ObjectNodeRef,
) -> bool {
!self
.matches(Some(subject), Some(predicate), Some(object))
.is_empty()
}
fn matches(
&self,
subject: Option<&SubjectNodeRef>,
predicate: Option<&IRIRef>,
object: Option<&ObjectNodeRef>,
) -> HashSet<&StatementRef>;
fn statements<'a>(&'a self) -> Box<dyn Iterator<Item = &'a StatementRef> + 'a>;
fn subjects(&self) -> HashSet<&SubjectNodeRef>;
fn predicates(&self) -> HashSet<&IRIRef>;
fn predicates_for(&self, subject: &SubjectNodeRef) -> HashSet<&IRIRef>;
fn objects(&self) -> HashSet<&ObjectNodeRef>;
fn objects_for(&self, subject: &SubjectNodeRef, predicate: &IRIRef) -> HashSet<&ObjectNodeRef>;
fn has_index(&self, index: &GraphIndex) -> bool;
fn has_indices(&self, indices: &[GraphIndex]) -> bool {
indices.iter().all(|i| self.has_index(i))
}
fn prefix_mappings(&self) -> Rc<RefCell<PrefixMappings>>;
fn set_prefix_mappings(&mut self, mappings: Rc<RefCell<PrefixMappings>>);
fn value_factory(&self) -> Option<Arc<dyn ValueFactory>> {
None
}
fn factory(&self) -> GraphFactoryRef;
fn statements_mut<'a>(&'a mut self) -> Box<dyn Iterator<Item = &'a mut StatementRef> + 'a>;
fn insert(&mut self, statement: StatementRef);
fn merge(&mut self, other: &Self)
where
Self: Sized;
fn dedup(&mut self);
fn remove(&mut self, statement: &StatementRef);
fn remove_all_for(&mut self, subject: &SubjectNodeRef);
fn clear(&mut self);
}
impl Display for GraphIndex {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
GraphIndex::Subject => "S",
GraphIndex::Predicate => "P",
GraphIndex::Object => "O",
GraphIndex::SubjectPredicate => "SP",
GraphIndex::SubjectPredicateObject => "SPO",
GraphIndex::SubjectObject => "SO",
GraphIndex::PredicateObject => "PO",
}
)
}
}
pub mod caching;
pub use caching::ValueFactory;
pub mod mapping;
pub use mapping::{Prefix, PrefixMappingRef, PrefixMappings};
pub mod skolem;