pacsea/logic/query.rs
1//! Search query dispatch and ID management for result correlation.
2
3use tokio::sync::mpsc;
4
5use crate::state::AppState;
6
7/// What: Send the current query text over the search channel with a fresh id.
8///
9/// Inputs:
10/// - `app`: Mutable application state; updates `next_query_id` and `latest_query_id`
11/// - `query_tx`: Channel to send the `QueryInput`
12///
13/// Output:
14/// - Sends a `QueryInput` with incremented id and current text; updates ids in `app`.
15///
16/// Details:
17/// - The id allows correlating responses so the UI can discard stale results.
18/// - Cache checking happens in `handle_search_results` to avoid architectural changes.
19pub fn send_query(app: &mut AppState, query_tx: &mpsc::UnboundedSender<crate::state::QueryInput>) {
20 let id = app.next_query_id;
21 app.next_query_id += 1;
22 app.latest_query_id = id;
23 let _ = query_tx.send(crate::state::QueryInput {
24 id,
25 text: app.input.clone(),
26 fuzzy: app.fuzzy_search_enabled,
27 });
28}
29
30#[cfg(test)]
31mod tests {
32 use super::*;
33
34 #[tokio::test]
35 /// What: Ensure `send_query` increments identifiers and forwards the current input text.
36 ///
37 /// Inputs:
38 /// - `AppState` whose `input` is set to `"hello"`.
39 ///
40 /// Output:
41 /// - `latest_query_id` advances to `1` and the channel receives a matching `QueryInput`.
42 ///
43 /// Details:
44 /// - Uses a short timeout to guarantee the send occurs asynchronously.
45 async fn send_query_increments_and_sends() {
46 let mut app = AppState {
47 input: "hello".into(),
48 ..Default::default()
49 };
50 let (tx, mut rx) = mpsc::unbounded_channel();
51 send_query(&mut app, &tx);
52 assert_eq!(app.latest_query_id, 1);
53 let q = tokio::time::timeout(std::time::Duration::from_millis(50), rx.recv())
54 .await
55 .ok()
56 .flatten()
57 .expect("query sent");
58 assert_eq!(q.id, app.latest_query_id);
59 assert_eq!(q.text, "hello");
60 assert!(!q.fuzzy); // Default is false
61 }
62}