use super::*;
use crate::graph::{GTerm, Graph, MutableGraph};
use crate::quad::Spog;
use crate::term::{GraphName, Term};
use crate::triple::Triple;
#[derive(Clone, Copy, Debug)]
pub struct GraphAsDataset<T>(T);
impl<T> GraphAsDataset<T>
where
T: Graph,
{
pub fn new(graph: T) -> Self {
GraphAsDataset(graph)
}
pub fn unwrap(self) -> T {
self.0
}
}
impl<T> Dataset for GraphAsDataset<T>
where
T: Graph,
{
type Quad<'x> = Spog<GTerm<'x, T>> where Self: 'x;
type Error = T::Error;
fn quads(&self) -> DQuadSource<Self> {
Box::new(
self.0
.triples()
.map(|r| r.map(Triple::into_quad)),
)
}
fn quads_matching<'s, S, P, O, G>(&'s self, sm: S, pm: P, om: O, gm: G) -> DQuadSource<'s, Self>
where
S: TermMatcher + 's,
P: TermMatcher + 's,
O: TermMatcher + 's,
G: GraphNameMatcher + 's,
{
if gm.matches(None as GraphName<>erm<T>>) {
Box::new(
self.0
.triples_matching(sm, pm, om)
.map(|r| r.map(Triple::into_quad)),
)
} else {
Box::new(std::iter::empty())
}
}
fn contains<TS, TP, TO, TG>(&self, s: TS, p: TP, o: TO, g: GraphName<TG>) -> DResult<Self, bool>
where
TS: Term,
TP: Term,
TO: Term,
TG: Term,
{
if g.is_none() {
self.0.contains(s, p, o)
} else {
Ok(false)
}
}
fn subjects(&self) -> DTermSource<Self> {
self.0.subjects()
}
fn predicates(&self) -> DTermSource<Self> {
self.0.predicates()
}
fn objects(&self) -> DTermSource<Self> {
self.0.objects()
}
fn graph_names(&self) -> DTermSource<Self> {
Box::new(std::iter::empty())
}
fn iris(&self) -> DTermSource<Self> {
self.0.iris()
}
fn blank_nodes(&self) -> DTermSource<Self> {
self.0.blank_nodes()
}
fn literals(&self) -> DTermSource<Self> {
self.0.literals()
}
fn quoted_triples<'s>(&'s self) -> DTermSource<'s, Self>
where
GTerm<'s, T>: Clone,
{
self.0.quoted_triples()
}
fn variables(&self) -> DTermSource<Self> {
self.0.variables()
}
}
impl<T> MutableDataset for GraphAsDataset<T>
where
T: MutableGraph,
{
type MutationError = GraphAsDatasetMutationError<T::MutationError>;
fn insert<TS, TP, TO, TG>(
&mut self,
s: TS,
p: TP,
o: TO,
g: GraphName<TG>,
) -> MdResult<Self, bool>
where
TS: Term,
TP: Term,
TO: Term,
TG: Term,
{
if g.is_none() {
self.0
.insert(s, p, o)
.map_err(GraphAsDatasetMutationError::Graph)
} else {
Err(GraphAsDatasetMutationError::OnlyDefaultGraph)
}
}
fn remove<TS, TP, TO, TG>(
&mut self,
s: TS,
p: TP,
o: TO,
g: GraphName<TG>,
) -> MdResult<Self, bool>
where
TS: Term,
TP: Term,
TO: Term,
TG: Term,
{
if g.is_none() {
self.0
.insert(s, p, o)
.map_err(GraphAsDatasetMutationError::Graph)
} else {
Ok(false)
}
}
}
#[derive(thiserror::Error, Debug)]
pub enum GraphAsDatasetMutationError<T: Error> {
#[error("{0:?}")]
Graph(T),
#[error("This dataset only supports a default graph")]
OnlyDefaultGraph,
}
#[cfg(test)]
mod test {
use super::*;
use crate::graph::adapter::DatasetGraph;
use crate::source::{StreamError, TripleSource};
use std::collections::BTreeSet;
type MyTerm = SimpleTerm<'static>;
type MyGraph = BTreeSet<[MyTerm; 3]>;
type MyGaDG = DatasetGraph<GraphAsDataset<MyGraph>, MyTerm>;
fn collect_graph_as_dataset<T: TripleSource>(ts: T) -> Result<MyGaDG, T::Error> {
ts.collect_triples()
.map(|g: MyGraph| DatasetGraph::new(g.into_dataset(), None))
.map_err(StreamError::unwrap_source_error)
}
crate::test_immutable_graph_impl!(
graph_as_dataset,
MyGaDG,
true,
true,
collect_graph_as_dataset
);
#[allow(dead_code)] fn check_trait_impls() {
let mut g: Vec<[SimpleTerm; 3]> = vec![];
for _ in g.as_dataset().quads() {}
let mut gd = g.as_dataset_mut();
for _ in gd.quads() {}
gd.remove_quad(([1, 2, 3], None)).unwrap();
let mut gd = g.into_dataset();
for _ in gd.quads() {}
gd.remove_quad(([1, 2, 3], None)).unwrap();
}
}