spareval/model.rs
1use crate::error::QueryEvaluationError;
2use oxrdf::{Triple, Variable};
3pub use sparesults::QuerySolution;
4use std::sync::Arc;
5
6/// Results of a [SPARQL query](https://www.w3.org/TR/sparql11-query/).
7pub enum QueryResults {
8 /// Results of a [SELECT](https://www.w3.org/TR/sparql11-query/#select) query.
9 Solutions(QuerySolutionIter),
10 /// Result of a [ASK](https://www.w3.org/TR/sparql11-query/#ask) query.
11 Boolean(bool),
12 /// Results of a [CONSTRUCT](https://www.w3.org/TR/sparql11-query/#construct) or [DESCRIBE](https://www.w3.org/TR/sparql11-query/#describe) query.
13 Graph(QueryTripleIter),
14}
15
16impl From<QuerySolutionIter> for QueryResults {
17 #[inline]
18 fn from(value: QuerySolutionIter) -> Self {
19 Self::Solutions(value)
20 }
21}
22
23/// An iterator over [`QuerySolution`]s.
24///
25/// ```
26/// use oxrdf::Dataset;
27/// use spareval::{QueryEvaluator, QueryResults};
28/// use spargebra::Query;
29///
30/// let query = Query::parse("SELECT ?s ?o WHERE { ?s ?p ?o }", None)?;
31/// if let QueryResults::Solutions(solutions) =
32/// QueryEvaluator::new().execute(Dataset::new(), &query)?
33/// {
34/// for solution in solutions {
35/// println!("{:?}", solution?.get("s"));
36/// }
37/// }
38/// # Result::<_, Box<dyn std::error::Error>>::Ok(())
39/// ```
40pub struct QuerySolutionIter {
41 variables: Arc<[Variable]>,
42 iter: Box<dyn Iterator<Item = Result<QuerySolution, QueryEvaluationError>>>,
43}
44
45impl QuerySolutionIter {
46 /// Construct a new iterator of solution from an ordered list of solution variables and an iterator of solution tuples
47 /// (each tuple using the same ordering as the variable list such that tuple element 0 is the value for the variable 0...)
48 pub fn new(
49 variables: Arc<[Variable]>,
50 iter: impl Iterator<Item = Result<QuerySolution, QueryEvaluationError>> + 'static,
51 ) -> Self {
52 Self {
53 variables,
54 iter: Box::new(iter),
55 }
56 }
57
58 /// The variables used in the solutions.
59 ///
60 /// ```
61 /// use oxrdf::{Dataset, Variable};
62 /// use spareval::{QueryEvaluator, QueryResults};
63 /// use spargebra::Query;
64 ///
65 /// let query = Query::parse("SELECT ?s ?o WHERE { ?s ?p ?o }", None)?;
66 /// if let QueryResults::Solutions(solutions) =
67 /// QueryEvaluator::new().execute(Dataset::new(), &query)?
68 /// {
69 /// assert_eq!(
70 /// solutions.variables(),
71 /// &[Variable::new("s")?, Variable::new("o")?]
72 /// );
73 /// }
74 /// # Result::<_, Box<dyn std::error::Error>>::Ok(())
75 /// ```
76 #[inline]
77 pub fn variables(&self) -> &[Variable] {
78 &self.variables
79 }
80}
81
82impl Iterator for QuerySolutionIter {
83 type Item = Result<QuerySolution, QueryEvaluationError>;
84
85 #[inline]
86 fn next(&mut self) -> Option<Self::Item> {
87 self.iter.next()
88 }
89
90 #[inline]
91 fn size_hint(&self) -> (usize, Option<usize>) {
92 self.iter.size_hint()
93 }
94}
95
96/// An iterator over the triples that compose a graph solution.
97///
98/// ```
99/// use oxrdf::Dataset;
100/// use spareval::{QueryEvaluator, QueryResults};
101/// use spargebra::Query;
102///
103/// let query = Query::parse("CONSTRUCT WHERE { ?s ?p ?o }", None)?;
104/// if let QueryResults::Graph(triples) = QueryEvaluator::new().execute(Dataset::new(), &query)? {
105/// for triple in triples {
106/// println!("{}", triple?);
107/// }
108/// }
109/// # Result::<_, Box<dyn std::error::Error>>::Ok(())
110/// ```
111pub struct QueryTripleIter {
112 iter: Box<dyn Iterator<Item = Result<Triple, QueryEvaluationError>>>,
113}
114
115impl QueryTripleIter {
116 pub(crate) fn new(
117 iter: impl Iterator<Item = Result<Triple, QueryEvaluationError>> + 'static,
118 ) -> Self {
119 Self {
120 iter: Box::new(iter),
121 }
122 }
123}
124
125impl Iterator for QueryTripleIter {
126 type Item = Result<Triple, QueryEvaluationError>;
127
128 #[inline]
129 fn next(&mut self) -> Option<Self::Item> {
130 self.iter.next()
131 }
132
133 #[inline]
134 fn size_hint(&self) -> (usize, Option<usize>) {
135 self.iter.size_hint()
136 }
137}