1use crate::error::QueryEvaluationError;
2use oxrdf::{Term, Triple, Variable};
3pub use sparesults::QuerySolution;
4use sparesults::{
5 ReaderQueryResultsParserOutput, ReaderSolutionsParser, SliceQueryResultsParserOutput,
6 SliceSolutionsParser,
7};
8use std::io::Read;
9use std::sync::Arc;
10
11pub enum QueryResults<'a> {
13 Solutions(QuerySolutionIter<'a>),
15 Boolean(bool),
17 Graph(QueryTripleIter<'a>),
19}
20
21impl<'a> From<QuerySolutionIter<'a>> for QueryResults<'a> {
22 #[inline]
23 fn from(value: QuerySolutionIter<'a>) -> Self {
24 Self::Solutions(value)
25 }
26}
27
28impl From<bool> for QueryResults<'_> {
29 #[inline]
30 fn from(value: bool) -> Self {
31 Self::Boolean(value)
32 }
33}
34
35impl<'a> From<QueryTripleIter<'a>> for QueryResults<'a> {
36 #[inline]
37 fn from(value: QueryTripleIter<'a>) -> Self {
38 Self::Graph(value)
39 }
40}
41
42impl<'a, R: Read + 'a> From<ReaderQueryResultsParserOutput<R>> for QueryResults<'a> {
43 #[inline]
44 fn from(output: ReaderQueryResultsParserOutput<R>) -> Self {
45 match output {
46 ReaderQueryResultsParserOutput::Solutions(output) => Self::Solutions(output.into()),
47 ReaderQueryResultsParserOutput::Boolean(output) => Self::Boolean(output),
48 }
49 }
50}
51
52impl<'a> From<SliceQueryResultsParserOutput<'a>> for QueryResults<'a> {
53 #[inline]
54 fn from(output: SliceQueryResultsParserOutput<'a>) -> Self {
55 match output {
56 SliceQueryResultsParserOutput::Solutions(output) => Self::Solutions(output.into()),
57 SliceQueryResultsParserOutput::Boolean(output) => Self::Boolean(output),
58 }
59 }
60}
61
62pub struct QuerySolutionIter<'a> {
80 variables: Arc<[Variable]>,
81 iter: Box<dyn Iterator<Item = Result<QuerySolution, QueryEvaluationError>> + 'a>,
82}
83
84impl<'a> QuerySolutionIter<'a> {
85 pub fn new(
87 variables: Arc<[Variable]>,
88 iter: impl IntoIterator<Item = Result<QuerySolution, QueryEvaluationError>> + 'a,
89 ) -> Self {
90 Self {
91 variables,
92 iter: Box::new(iter.into_iter()),
93 }
94 }
95
96 pub fn from_tuples(
99 variables: Arc<[Variable]>,
100 iter: impl IntoIterator<Item = Result<Vec<Option<Term>>, QueryEvaluationError>> + 'a,
101 ) -> Self {
102 Self::new(
103 Arc::clone(&variables),
104 iter.into_iter()
105 .map(move |values| Ok((Arc::clone(&variables), values?).into())),
106 )
107 }
108
109 #[inline]
128 pub fn variables(&self) -> &[Variable] {
129 &self.variables
130 }
131}
132
133impl Iterator for QuerySolutionIter<'_> {
134 type Item = Result<QuerySolution, QueryEvaluationError>;
135
136 #[inline]
137 fn next(&mut self) -> Option<Self::Item> {
138 self.iter.next()
139 }
140
141 #[inline]
142 fn size_hint(&self) -> (usize, Option<usize>) {
143 self.iter.size_hint()
144 }
145}
146
147impl<'a, R: Read + 'a> From<ReaderSolutionsParser<R>> for QuerySolutionIter<'a> {
148 #[inline]
149 fn from(parser: ReaderSolutionsParser<R>) -> Self {
150 Self {
151 variables: parser.variables().into(),
152 iter: Box::new(
153 parser.map(|r| r.map_err(|e| QueryEvaluationError::Unexpected(e.into()))),
154 ),
155 }
156 }
157}
158
159impl<'a> From<SliceSolutionsParser<'a>> for QuerySolutionIter<'a> {
160 #[inline]
161 fn from(parser: SliceSolutionsParser<'a>) -> Self {
162 Self {
163 variables: parser.variables().into(),
164 iter: Box::new(
165 parser.map(|r| r.map_err(|e| QueryEvaluationError::Unexpected(e.into()))),
166 ),
167 }
168 }
169}
170
171pub struct QueryTripleIter<'a> {
188 iter: Box<dyn Iterator<Item = Result<Triple, QueryEvaluationError>> + 'a>,
189}
190
191impl<'a> QueryTripleIter<'a> {
192 pub fn new(iter: impl Iterator<Item = Result<Triple, QueryEvaluationError>> + 'a) -> Self {
193 Self {
194 iter: Box::new(iter),
195 }
196 }
197}
198
199impl Iterator for QueryTripleIter<'_> {
200 type Item = Result<Triple, QueryEvaluationError>;
201
202 #[inline]
203 fn next(&mut self) -> Option<Self::Item> {
204 self.iter.next()
205 }
206
207 #[inline]
208 fn size_hint(&self) -> (usize, Option<usize>) {
209 self.iter.size_hint()
210 }
211}