1use super::*;
3use crate::graph::{GTerm, Graph, MutableGraph};
4use crate::quad::Spog;
5use crate::term::{GraphName, Term};
6use crate::triple::Triple;
7
8#[derive(Clone, Copy, Debug)]
10pub struct GraphAsDataset<T>(T);
11
12impl<T> GraphAsDataset<T>
13where
14 T: Graph,
15{
16 pub fn new(graph: T) -> Self {
18 GraphAsDataset(graph)
19 }
20
21 pub fn unwrap(self) -> T {
23 self.0
24 }
25}
26
27impl<T> Dataset for GraphAsDataset<T>
28where
29 T: Graph,
30{
31 type Quad<'x> = Spog<GTerm<'x, T>> where Self: 'x;
32 type Error = T::Error;
33
34 fn quads(&self) -> DQuadSource<Self> {
35 Box::new(
36 self.0
37 .triples()
38 .map(|r| r.map(Triple::into_quad)),
40 )
41 }
42
43 fn quads_matching<'s, S, P, O, G>(&'s self, sm: S, pm: P, om: O, gm: G) -> DQuadSource<'s, Self>
44 where
45 S: TermMatcher + 's,
46 P: TermMatcher + 's,
47 O: TermMatcher + 's,
48 G: GraphNameMatcher + 's,
49 {
50 if gm.matches(None as GraphName<>erm<T>>) {
51 Box::new(
52 self.0
53 .triples_matching(sm, pm, om)
54 .map(|r| r.map(Triple::into_quad)),
56 )
57 } else {
58 Box::new(std::iter::empty())
59 }
60 }
61
62 fn contains<TS, TP, TO, TG>(&self, s: TS, p: TP, o: TO, g: GraphName<TG>) -> DResult<Self, bool>
63 where
64 TS: Term,
65 TP: Term,
66 TO: Term,
67 TG: Term,
68 {
69 if g.is_none() {
70 self.0.contains(s, p, o)
71 } else {
72 Ok(false)
73 }
74 }
75
76 fn subjects(&self) -> DTermSource<Self> {
77 self.0.subjects()
78 }
79
80 fn predicates(&self) -> DTermSource<Self> {
81 self.0.predicates()
82 }
83
84 fn objects(&self) -> DTermSource<Self> {
85 self.0.objects()
86 }
87
88 fn graph_names(&self) -> DTermSource<Self> {
89 Box::new(std::iter::empty())
90 }
91
92 fn iris(&self) -> DTermSource<Self> {
93 self.0.iris()
94 }
95
96 fn blank_nodes(&self) -> DTermSource<Self> {
97 self.0.blank_nodes()
98 }
99
100 fn literals(&self) -> DTermSource<Self> {
101 self.0.literals()
102 }
103
104 fn quoted_triples<'s>(&'s self) -> DTermSource<'s, Self>
105 where
106 GTerm<'s, T>: Clone,
107 {
108 self.0.quoted_triples()
109 }
110
111 fn variables(&self) -> DTermSource<Self> {
112 self.0.variables()
113 }
114}
115
116impl<T> MutableDataset for GraphAsDataset<T>
117where
118 T: MutableGraph,
119{
120 type MutationError = GraphAsDatasetMutationError<T::MutationError>;
121
122 fn insert<TS, TP, TO, TG>(
123 &mut self,
124 s: TS,
125 p: TP,
126 o: TO,
127 g: GraphName<TG>,
128 ) -> MdResult<Self, bool>
129 where
130 TS: Term,
131 TP: Term,
132 TO: Term,
133 TG: Term,
134 {
135 if g.is_none() {
136 self.0
137 .insert(s, p, o)
138 .map_err(GraphAsDatasetMutationError::Graph)
139 } else {
140 Err(GraphAsDatasetMutationError::OnlyDefaultGraph)
141 }
142 }
143
144 fn remove<TS, TP, TO, TG>(
145 &mut self,
146 s: TS,
147 p: TP,
148 o: TO,
149 g: GraphName<TG>,
150 ) -> MdResult<Self, bool>
151 where
152 TS: Term,
153 TP: Term,
154 TO: Term,
155 TG: Term,
156 {
157 if g.is_none() {
158 self.0
159 .insert(s, p, o)
160 .map_err(GraphAsDatasetMutationError::Graph)
161 } else {
162 Ok(false)
163 }
164 }
165}
166
167#[derive(thiserror::Error, Debug)]
172pub enum GraphAsDatasetMutationError<T: Error> {
173 #[error("{0:?}")]
175 Graph(T),
176 #[error("This dataset only supports a default graph")]
178 OnlyDefaultGraph,
179}
180
181#[cfg(test)]
182mod test {
183 use super::*;
184 use crate::graph::adapter::DatasetGraph;
185 use crate::source::{StreamError, TripleSource};
186 use std::collections::BTreeSet;
187
188 type MyTerm = SimpleTerm<'static>;
189 type MyGraph = BTreeSet<[MyTerm; 3]>;
190
191 type MyGaDG = DatasetGraph<GraphAsDataset<MyGraph>, MyTerm>;
197 fn collect_graph_as_dataset<T: TripleSource>(ts: T) -> Result<MyGaDG, T::Error> {
198 ts.collect_triples()
199 .map(|g: MyGraph| DatasetGraph::new(g.into_dataset(), None))
200 .map_err(StreamError::unwrap_source_error)
201 }
202 crate::test_immutable_graph_impl!(
203 graph_as_dataset,
204 MyGaDG,
205 true,
206 true,
207 collect_graph_as_dataset
208 );
209
210 #[allow(dead_code)] fn check_trait_impls() {
212 let mut g: Vec<[SimpleTerm; 3]> = vec![];
213
214 for _ in g.as_dataset().quads() {}
216
217 let mut gd = g.as_dataset_mut();
218 for _ in gd.quads() {}
220 gd.remove_quad(([1, 2, 3], None)).unwrap();
222
223 let mut gd = g.into_dataset();
224 for _ in gd.quads() {}
226 gd.remove_quad(([1, 2, 3], None)).unwrap();
228 }
229}