Skip to main content

io_email/search/
query.rs

1//! # Search emails query
2//!
3//! This module exposes [`SearchEmailsQuery`], the top-level structure
4//! that wraps a [`SearchEmailsFilterQuery`] (filter) and a
5//! [`SearchEmailsSortQuery`] (sort).
6//!
7//! The query can be parsed from a string slice via [`FromStr`]; see
8//! [`super::parser`] for the parser entry point and the grammar.
9
10use core::str::FromStr;
11
12use crate::search::{
13    error::Error, filter::query::SearchEmailsFilterQuery, parser,
14    sort::query::SearchEmailsSortQuery,
15};
16
17/// The search emails query structure.
18///
19/// Composed of an optional recursive [`SearchEmailsFilterQuery`] and an
20/// optional [`SearchEmailsSortQuery`]. At least one of the two must be
21/// present in a valid query string.
22#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
23pub struct SearchEmailsQuery {
24    /// The recursive emails search filter query.
25    pub filter: Option<SearchEmailsFilterQuery>,
26
27    /// The emails search sort query.
28    pub sort: Option<SearchEmailsSortQuery>,
29}
30
31impl FromStr for SearchEmailsQuery {
32    type Err = Error;
33
34    fn from_str(s: &str) -> Result<Self, Self::Err> {
35        parser::parse(s)
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use alloc::{boxed::Box, vec};
42
43    use crate::search::{
44        filter::query::SearchEmailsFilterQuery,
45        query::SearchEmailsQuery,
46        sort::query::{SearchEmailsSorterKind::*, SearchEmailsSorterOrder::*},
47    };
48
49    #[test]
50    fn filters_only() {
51        assert_eq!(
52            "from f and to t".parse::<SearchEmailsQuery>().unwrap(),
53            SearchEmailsQuery {
54                filter: Some(SearchEmailsFilterQuery::And(
55                    Box::new(SearchEmailsFilterQuery::From("f".into())),
56                    Box::new(SearchEmailsFilterQuery::To("t".into())),
57                )),
58                sort: None,
59            },
60        );
61    }
62
63    #[test]
64    fn sorters_only() {
65        assert_eq!(
66            "order by from".parse::<SearchEmailsQuery>().unwrap(),
67            SearchEmailsQuery {
68                filter: None,
69                sort: Some(vec![From.into()]),
70            },
71        );
72
73        assert_eq!(
74            "order by from asc subject desc"
75                .parse::<SearchEmailsQuery>()
76                .unwrap(),
77            SearchEmailsQuery {
78                filter: None,
79                sort: Some(vec![From.into(), (Subject, Descending).into()]),
80            },
81        );
82    }
83
84    #[test]
85    fn full() {
86        assert_eq!(
87            "from f and to t order by from to desc"
88                .parse::<SearchEmailsQuery>()
89                .unwrap(),
90            SearchEmailsQuery {
91                filter: Some(SearchEmailsFilterQuery::And(
92                    Box::new(SearchEmailsFilterQuery::From("f".into())),
93                    Box::new(SearchEmailsFilterQuery::To("t".into())),
94                )),
95                sort: Some(vec![From.into(), (To, Descending).into()]),
96            },
97        );
98    }
99}