1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4
5use crate::doc::HalDoc;
6
7#[derive(Clone, Debug, Serialize, Deserialize)]
9pub struct SearchResponse {
10 pub response: ResponseBody,
12 #[serde(default)]
14 pub facet_counts: Option<FacetCounts>,
15}
16
17impl SearchResponse {
18 pub fn num_found(&self) -> i64 {
20 self.response.num_found
21 }
22
23 pub fn start(&self) -> i64 {
25 self.response.start
26 }
27
28 pub fn docs(&self) -> &[HalDoc] {
30 &self.response.docs
31 }
32
33 pub fn facets(&self) -> Option<&FacetCounts> {
35 self.facet_counts.as_ref()
36 }
37}
38
39#[derive(Clone, Debug, Serialize, Deserialize)]
41pub struct ResponseBody {
42 #[serde(rename = "numFound")]
44 pub num_found: i64,
45 pub start: i64,
47 pub docs: Vec<HalDoc>,
49}
50
51#[derive(Clone, Debug, Default, Serialize, Deserialize)]
56pub struct FacetCounts {
57 #[serde(default)]
59 pub facet_fields: HashMap<String, Vec<serde_json::Value>>,
60}
61
62impl FacetCounts {
63 pub fn field(&self, name: &str) -> Vec<(String, i64)> {
65 let Some(raw) = self.facet_fields.get(name) else {
66 return Vec::new();
67 };
68 raw.chunks_exact(2)
69 .filter_map(|pair| {
70 let value = pair[0].as_str()?.to_owned();
71 let count = pair[1].as_i64()?;
72 Some((value, count))
73 })
74 .collect()
75 }
76}