Skip to main content

tix/
search.rs

1//! Shared search corpus and matchers for `tix search` (CLI, WP04) and the
2//! `/` search (TUI, WP05).
3//!
4//! Both consumers search **exactly the same corpus**: the complete serialized
5//! markdown of every issue (`Issue::to_file_contents()`, i.e. frontmatter +
6//! body + comments). A single engine here keeps the CLI and TUI behavior from
7//! drifting (C-005, FR-012):
8//!
9//! - [`Corpus::build`] snapshots every issue's full file text.
10//! - [`search_substring`] is the case-insensitive single-occurrence matcher
11//!   the CLI uses, returning matched-line context.
12//! - [`query_matches`] is the grammar-aware matcher (`key:value` tokens plus
13//!   case-insensitive **substring** bare terms) the board's `/` search uses.
14//! - [`fuzzy_score`] is the deterministic subsequence scorer, now used only as
15//!   the help overlay's fallback when a literal substring finds no row (tix
16//!   #1496); the board's `/` search no longer uses it (tix #1498).
17//!
18//! Nothing here touches the `-assets/` directories (C-005): binary contents
19//! are never indexed, and [`Corpus::build`] inherits that from
20//! [`Store::list`], which already excludes non-`.md` files and `-assets` dirs.
21
22use serde::{Deserialize, Serialize};
23
24use crate::error::{Result, TixError};
25use crate::model::Issue;
26use crate::storage::Store;
27use crate::watcher::FsDelta;
28use std::collections::HashSet;
29use std::path::{Path, PathBuf};
30
31mod corpus;
32mod filter;
33mod query;
34pub use corpus::*;
35pub use filter::*;
36pub use query::*;
37
38// ---------------------------------------------------------------------------
39// Structured filtering (FR-007..FR-013)
40// ---------------------------------------------------------------------------
41
42#[cfg(test)]
43mod tests;