1use mant_ir::ResolvedContent;
3use mant_loader::{DocumentLoader, LoadError, LoadPolicy, LoadSpec, validate_load_spec};
4use mant_protocol::{
5 EntryProjection, MAX_NODE_SELECTORS, MAX_SEMANTIC_ENTRY_CHARS, QueryExcerpt, QueryInput,
6 QueryOutline, QueryRequest, QuerySearch, QueryView, ScopeTextError, SearchQuery,
7 validate_scope_text,
8};
9use mant_query::{
10 ProjectionError, SearchError, search_query, select_excerpt, validate_search_query,
11};
12use std::{error::Error, fmt};
13mod adapter;
14mod execution;
15mod prepared;
16pub use prepared::PreparedQueryRequest;
17mod validation;
18mod validation_error;
19pub use adapter::DocumentResolver;
20pub use execution::project_query_view;
21pub use validation::validate_query_request;
22pub use validation_error::QueryValidationError;
23#[derive(Debug, Clone, PartialEq, Eq)]
25pub enum QueryError {
26 Load(LoadError),
28 QueryValidation(QueryValidationError),
30}
31
32impl From<LoadError> for QueryError {
33 fn from(error: LoadError) -> Self {
34 Self::Load(error)
35 }
36}
37impl From<QueryValidationError> for QueryError {
38 fn from(error: QueryValidationError) -> Self {
39 Self::QueryValidation(error)
40 }
41}
42impl fmt::Display for QueryError {
43 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
44 match self {
45 Self::Load(error) => error.fmt(formatter),
46 Self::QueryValidation(error) => error.fmt(formatter),
47 }
48 }
49}
50impl Error for QueryError {
51 fn source(&self) -> Option<&(dyn Error + 'static)> {
52 match self {
53 Self::Load(error) => Some(error),
54 Self::QueryValidation(error) => Some(error),
55 }
56 }
57}
58
59#[derive(Debug, Clone, PartialEq, Eq)]
61pub enum QueryViewResult {
62 Full(Box<ResolvedContent>),
64 Outline(QueryOutline),
66 Excerpt(QueryExcerpt),
68 Explanation(mant_protocol::QueryExplanation),
70 Search(QuerySearch),
72}
73
74#[derive(Debug, Clone, PartialEq, Eq)]
76pub enum QueryExecutionError {
77 Query(QueryError),
79 Projection(ProjectionError),
81 Search(SearchError),
83}
84
85impl fmt::Display for QueryExecutionError {
86 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
87 match self {
88 Self::Query(error) => error.fmt(formatter),
89 Self::Projection(error) => error.fmt(formatter),
90 Self::Search(error) => error.fmt(formatter),
91 }
92 }
93}
94
95impl Error for QueryExecutionError {
96 fn source(&self) -> Option<&(dyn Error + 'static)> {
97 match self {
98 Self::Query(error) => Some(error),
99 Self::Projection(error) => Some(error),
100 Self::Search(error) => Some(error),
101 }
102 }
103}
104
105pub fn resolve_query(request: &QueryRequest) -> Result<ResolvedContent, QueryError> {
112 resolve_query_with_policy(request, LoadPolicy::default())
113}
114
115pub fn resolve_query_with_policy(
123 request: &QueryRequest,
124 policy: LoadPolicy,
125) -> Result<ResolvedContent, QueryError> {
126 let (prepared, resolver) = validated_resolver(request, policy, DocumentResolver::from_system)?;
127 prepared.resolve(&resolver)
128}
129
130pub fn execute_query(
138 request: &QueryRequest,
139 policy: LoadPolicy,
140) -> Result<QueryViewResult, QueryExecutionError> {
141 let (prepared, resolver) = validated_resolver(request, policy, DocumentResolver::from_system)
142 .map_err(QueryExecutionError::Query)?;
143 prepared.execute(&resolver)
144}
145
146fn validated_resolver<T>(
149 request: &QueryRequest,
150 policy: LoadPolicy,
151 factory: impl FnOnce() -> T,
152) -> Result<(PreparedQueryRequest<'_>, T), QueryError> {
153 let prepared = PreparedQueryRequest::new(request, policy)?;
154 Ok((prepared, factory()))
155}
156
157#[cfg(test)]
158mod tests;