Expand description
Parser and typed AST for Gmail-style email search queries.
use mail_query::{parse, FilterKind, QueryField, QueryNode};
let ast = parse("from:alice is:unread -has:attachment").expect("parses");
match ast {
QueryNode::And(_, _) => {} // top-level is a conjunction
other => panic!("expected And, got {other:?}"),
}The crate covers Gmail’s documented operator surface
(https://support.google.com/mail/answer/7190): address fields
(from:, to:, cc:, bcc:, deliveredto:, rfc822msgid:,
list:), content fields (subject:, body:, filename:), is:
and has: filters, label: and category:, size and date operators
with relative durations (older_than:5d), boolean operators (AND,
OR, NOT, -), and proximity (AROUND<n>). It also recognises
+word as an exact-match (no-stemming) hint.
§What this crate does not do
- It does not execute queries. The output is a portable
QueryNode; backends translate it to their own query language (tantivy, meilisearch, SQL FTS, IMAP SEARCH, …). - It does not resolve
older_than:5dto a concrete date at parse time. Backends do that when building an executable query, using their ownnow. This is what lets a saved query mean the same thing tomorrow as today and lets the AST round-trip throughDisplaywithout embedding a date. - It does not implement IMAP SEARCH grammar (RFC 3501 §6.4.4) — that is a separate, future crate. The vocabularies overlap but the grammars do not.
§Extensibility
Filter names that Gmail adds over time, or your application’s own
is:owed-reply, route through FilterKind::Custom. Register the
names you want to accept via ParserOptions::register_custom_filter
before calling parse_with.
use mail_query::{parse_with, FilterKind, ParserOptions, QueryNode};
let mut options = ParserOptions::new();
options.register_custom_filter("owed-reply");
let ast = parse_with("is:owed-reply", &options).expect("parses");
assert_eq!(
ast,
QueryNode::Filter(FilterKind::Custom("owed-reply".into()))
);§Feature flags
serde— addsSerialize/Deserializederives to every AST type.
§Forward compatibility
Every public enum is #[non_exhaustive]. New variants (for new Gmail
operators) are non-breaking additions. Pattern-matching callers must
include a _ => … arm.
Structs§
- Parser
Options - Caller-provided configuration for the parser.
Enums§
- Date
Bound - Date bound for
QueryNode::DateRange. - Date
Value - Date value for
QueryNode::DateRange. - Filter
Kind is:andhas:filter values.- Parse
Error - Errors returned by
parseandparse_with. - Query
Field - Built-in
field:names. New Gmail field operators will land as additional variants here. - Query
Node - Root AST node for a parsed query.
- Relative
Unit - Time unit for
DateValue::Relative. - SizeOp
- Comparison operator for
QueryNode::Size.
Traits§
- Visitor
- AST visitor.
Functions§
- parse
- Parse an email query string into a
QueryNodeAST. - parse_
with - Parse with caller-provided options. Use this to register custom
filter names (so e.g.
is:owed-replyparses toFilterKind::Custom("owed-reply")instead of returningParseError::UnknownFilter).