82 lines
3.0 KiB
Rust
82 lines
3.0 KiB
Rust
use anyhow::Result;
|
|
use common::proto::komp_ac::search::{
|
|
SearchCountResponse, SearchRequest, SearchResponse, searcher_client::SearcherClient,
|
|
};
|
|
use tonic::transport::Channel;
|
|
use tonic::Request;
|
|
|
|
#[derive(Clone)]
|
|
pub struct SearchGrpc {
|
|
client: SearcherClient<Channel>,
|
|
}
|
|
|
|
impl SearchGrpc {
|
|
pub fn new(channel: Channel) -> Self {
|
|
Self {
|
|
client: SearcherClient::new(channel),
|
|
}
|
|
}
|
|
|
|
pub async fn search(&mut self, request: Request<SearchRequest>) -> Result<SearchResponse> {
|
|
Ok(self.client.search(request).await?.into_inner())
|
|
}
|
|
|
|
pub async fn get_filtered_row(
|
|
&mut self,
|
|
request: Request<SearchRequest>,
|
|
) -> Result<common::proto::komp_ac::tables_data::GetTableDataResponse> {
|
|
Ok(self.client.get_filtered_row(request).await?.into_inner())
|
|
}
|
|
|
|
pub async fn batch_count(
|
|
&mut self,
|
|
request: Request<common::proto::komp_ac::search::BatchCountRequest>,
|
|
) -> Result<Vec<std::result::Result<u64, String>>> {
|
|
let expected = request.get_ref().requests.len();
|
|
let response = self.client.batch_count(request).await?.into_inner();
|
|
decode_batch_counts(response, expected)
|
|
}
|
|
|
|
pub async fn count(&mut self, request: Request<SearchRequest>) -> Result<SearchCountResponse> {
|
|
Ok(self.client.count(request).await?.into_inner())
|
|
}
|
|
}
|
|
|
|
fn decode_batch_counts(
|
|
response: common::proto::komp_ac::search::BatchCountResponse,
|
|
expected: usize,
|
|
) -> Result<Vec<std::result::Result<u64, String>>> {
|
|
use common::proto::komp_ac::search::batch_count_result::Outcome;
|
|
anyhow::ensure!(response.results.len() == expected, "Server returned an incomplete count batch");
|
|
Ok(response.results.into_iter().map(|result| match result.outcome {
|
|
Some(Outcome::Count(count)) => Ok(count),
|
|
Some(Outcome::Error(error)) => Err(error),
|
|
None => Err("Server omitted a count result".to_string()),
|
|
}).collect())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod batch_count_tests {
|
|
use super::*;
|
|
use common::proto::komp_ac::search::{BatchCountResponse, BatchCountResult, batch_count_result::Outcome};
|
|
|
|
#[test]
|
|
fn batch_counts_preserve_zero_errors_and_missing_results() {
|
|
let response = BatchCountResponse { results: vec![
|
|
BatchCountResult { outcome: Some(Outcome::Count(0)) },
|
|
BatchCountResult { outcome: Some(Outcome::Error("denied".into())) },
|
|
BatchCountResult { outcome: None },
|
|
BatchCountResult { outcome: Some(Outcome::Count(7)) },
|
|
] };
|
|
let counts = decode_batch_counts(response, 4).unwrap();
|
|
assert_eq!(counts[0], Ok(0));
|
|
assert_eq!(counts[1], Err("denied".into()));
|
|
assert!(counts[2].is_err());
|
|
assert_eq!(counts[3], Ok(7));
|
|
assert!(decode_batch_counts(BatchCountResponse { results: Vec::new() }, 1).is_err());
|
|
assert!(decode_batch_counts(BatchCountResponse { results: vec![
|
|
BatchCountResult { outcome: Some(Outcome::Count(0)) },
|
|
] }, 0).is_err());
|
|
}
|
|
}
|