fmf_core\query/mod.rs
1//! Query engine: text → AST → compiled matchers → parallel scan →
2//! materialized, sort-ordered result (docs/ARCHITECTURE.md).
3//!
4//! Syntax (core):
5//! `space`=AND, `|`=OR (weakest), `!`=NOT, `"..."`=phrase, `*`/`?` wildcards
6//! (match the whole name), a `\` inside a term switches it to path matching,
7//! and the filters `ext:`, `path:`, `size:`, `dm:`, `regex:`, `file:`,
8//! `folder:`.
9
10mod ast;
11mod compile;
12mod dates;
13mod exec;
14mod matchers;
15mod memo;
16mod subsume;
17mod sweep;
18
19pub use ast::{Ast, ParseError, Term, parse};
20pub use compile::{CaseMode, CompileError, CompiledQuery, compile, compile_whole_regex};
21#[cfg(windows)]
22pub use dates::WindowsLocalResolver;
23pub use dates::{DateResolver, UtcResolver};
24pub(crate) use exec::refine;
25pub use exec::{SearchMetrics, SearchResult, search};
26pub use fmf_contract::options::RegexScope;
27pub use memo::{derived_cache_bytes, prewarm};
28pub(crate) use subsume::subsumes;
29
30use crate::index::SortKey;
31
32/// Per-query options controlling sort order, case handling, visibility, and
33/// whole-query regex mode — the engine-side form the wire options convert into.
34#[derive(Clone, Copy, Debug, PartialEq, Eq)]
35pub struct QueryOptions {
36 /// Which column the materialized result is sorted by (name, size, date…).
37 pub sort: SortKey,
38 /// Sort descending when set, ascending otherwise.
39 pub desc: bool,
40 /// Case-sensitivity policy applied to matchers (smart/sensitive/insensitive).
41 pub case: CaseMode,
42 /// Hidden/system entries (and everything under such branches) are
43 /// skipped unless this is set — the UI toggle maps straight here.
44 pub include_hidden_system: bool,
45 /// Treat the whole query text as one regex (`regex_mode` bit0) — the
46 /// engine skips parsing and compiles a single `regex_scope` matcher.
47 pub regex_mode: bool,
48 /// Which haystack the whole-query regex runs against (ignored unless
49 /// `regex_mode`).
50 pub regex_scope: RegexScope,
51}
52
53impl Default for QueryOptions {
54 fn default() -> Self {
55 Self {
56 sort: SortKey::Name,
57 desc: false,
58 case: CaseMode::Smart,
59 include_hidden_system: false,
60 regex_mode: false,
61 regex_scope: RegexScope::Name,
62 }
63 }
64}
65
66/// The single wire→engine options conversion — both boundaries (FFI
67/// `fmf_query` and pipe dispatch) go through this (ADR-0018). `regex_mode`
68/// is a packed u32: bit0 = whole-query regex on, bit1 = scope (0 name /
69/// 1 path).
70impl From<fmf_contract::pod::FmfQueryOptions> for QueryOptions {
71 fn from(o: fmf_contract::pod::FmfQueryOptions) -> Self {
72 Self {
73 sort: SortKey::from_u32(o.sort),
74 desc: o.desc != 0,
75 case: CaseMode::from_u32(o.case_mode),
76 include_hidden_system: o.include_hidden_system != 0,
77 regex_mode: o.regex_mode & 0b1 != 0,
78 regex_scope: RegexScope::from_u32((o.regex_mode >> 1) & 0b1),
79 }
80 }
81}