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