Skip to main content

AirLibrary/Client/AirClient/
SearchFiles.rs

1//! `AirClient::SearchFiles` - issues a content / path search against the
2//! Air daemon's `IndexingService` index.
3//!
4//! Returns an empty vector on success: the underlying
5//! `SearchFilesResponse` does not yet carry per-hit detail in the live
6//! proto, so the response is structural-only and downstream callers that
7//! need hits should consume `IndexInfo::Struct` or wait for the schema to
8//! grow per-hit fields.
9
10use tonic::Request;
11
12use crate::{
13	AirError,
14	Client::AirClient::{AirClient, FileResult},
15	Vine::Generated::air::SearchRequest,
16	dev_log,
17};
18
19impl AirClient {
20	/// Searches the index for files matching `query`.
21	///
22	/// # Arguments
23	///
24	/// - `request_id` - opaque correlation id.
25	/// - `query` - search expression (provider-defined syntax).
26	/// - `path` - root path to scope the search; empty = whole index.
27	/// - `max_results` - hard cap on hits returned.
28	pub async fn SearchFiles(
29		&self,
30
31		request_id:String,
32
33		query:String,
34
35		path:String,
36
37		max_results:u32,
38	) -> Result<Vec<FileResult::Struct>, AirError> {
39		dev_log!("grpc", "[AirClient] Searching for files with query: '{}' in: {}", query, path);
40
41		let RequestPayload = SearchRequest { request_id, query, path, max_results };
42
43		let Client = self
44			.Client()
45			.ok_or_else(|| AirError::Network("Air client not initialized".to_string()))?;
46
47		let mut ClientGuard = Client.lock().await;
48
49		match ClientGuard.search_files(Request::new(RequestPayload)).await {
50			Ok(_Response) => {
51				dev_log!("grpc", "[AirClient] Search completed");
52
53				// SearchFilesResponse does not carry per-hit detail yet.
54				Ok(Vec::new())
55			},
56
57			Err(Status) => {
58				dev_log!("grpc", "error: [AirClient] Search files RPC error: {}", Status);
59
60				Err(AirError::Network(format!("Search files RPC error: {}", Status)))
61			},
62		}
63	}
64}