io_email/search/
parser.rs1use alloc::{string::String, vec::Vec};
10
11use chumsky::{Parser, error::Rich, extra};
12
13use crate::search::{
14 error::Error,
15 filter::{self, query::SearchEmailsFilterQuery},
16 query::SearchEmailsQuery,
17 sort::{self, query::SearchEmailsSorter},
18};
19
20pub type ParserError<'a> = extra::Err<Rich<'a, char>>;
22
23pub fn parse(input: impl AsRef<str>) -> Result<SearchEmailsQuery, Error> {
33 let input = input.as_ref().trim();
34
35 if let Some((filters_input, sorters_input)) = input.rsplit_once("order by") {
36 if filters_input.trim().is_empty() {
37 let filter = None;
38 let sort = parse_sort(sorters_input).map(Some)?;
39 Ok(SearchEmailsQuery { filter, sort })
40 } else {
41 let filter = parse_filter(filters_input).map(Some)?;
42 let sort = parse_sort(sorters_input).map(Some)?;
43 Ok(SearchEmailsQuery { filter, sort })
44 }
45 } else {
46 let filter = parse_filter(input).map(Some)?;
47 let sort = None;
48 Ok(SearchEmailsQuery { filter, sort })
49 }
50}
51
52pub fn parse_filter(input: impl AsRef<str>) -> Result<SearchEmailsFilterQuery, Error> {
54 let input = input.as_ref().trim();
55
56 filter::parser::query()
57 .parse(input)
58 .into_result()
59 .map_err(|errs| {
60 let errs = errs
61 .into_iter()
62 .map(|err| err.clone().into_owned())
63 .collect();
64 Error::ParseError(errs, String::from(input))
65 })
66}
67
68pub fn parse_sort(input: impl AsRef<str>) -> Result<Vec<SearchEmailsSorter>, Error> {
70 let input = input.as_ref().trim();
71
72 sort::parser::query()
73 .parse(input)
74 .into_result()
75 .map_err(|errs| {
76 let errs = errs
77 .into_iter()
78 .map(|err| err.clone().into_owned())
79 .collect();
80 Error::ParseError(errs, String::from(input))
81 })
82}