use serde::{Deserialize, Deserializer, Serialize};
use serde_json::Value;
use std::collections::HashMap;
#[derive(Clone, Debug, Serialize, PartialEq)]
pub struct SolrJsonFacetResponse {
val: Option<Value>,
count: Option<usize>,
num_buckets: Option<usize>,
missing: Option<Box<SolrJsonFacetResponse>>,
all_buckets: Option<Box<SolrJsonFacetResponse>>,
#[serde(default)]
buckets: Vec<SolrJsonFacetResponse>,
#[serde(flatten)]
flat_facets: HashMap<String, Value>,
#[serde(default)]
nested_facets: HashMap<String, SolrJsonFacetResponse>,
}
impl SolrJsonFacetResponse {
pub fn get_val(&self) -> Option<&Value> {
self.val.as_ref()
}
pub fn get_buckets(&self) -> impl Iterator<Item = &SolrJsonFacetResponse> {
self.buckets.iter()
}
pub fn get_num_buckets(&self) -> Option<usize> {
self.num_buckets
}
pub fn get_missing(&self) -> Option<usize> {
self.missing.as_deref()?.get_count()
}
pub fn get_all_buckets(&self) -> Option<usize> {
self.all_buckets.as_deref()?.get_count()
}
pub fn get_flat_facets(&self) -> &HashMap<String, Value> {
&self.flat_facets
}
pub fn get_nested_facets(&self) -> &HashMap<String, SolrJsonFacetResponse> {
&self.nested_facets
}
pub fn get_count(&self) -> Option<usize> {
self.count
}
}
impl<'de> Deserialize<'de> for SolrJsonFacetResponse {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let mut map = HashMap::<String, Value>::deserialize(deserializer)?;
let count = map
.remove("count")
.and_then(|v| v.as_u64().map(|u| u as usize));
let val = map.remove("val");
let num_buckets = map
.remove("numBuckets")
.and_then(|v| v.as_u64().map(|u| u as usize));
let missing = map
.remove("missing")
.and_then(|v| serde_json::from_value::<SolrJsonFacetResponse>(v).ok());
let all_buckets = map
.remove("allBuckets")
.and_then(|v| serde_json::from_value::<SolrJsonFacetResponse>(v).ok());
let buckets = map
.remove("buckets")
.and_then(|b| serde_json::from_value::<Vec<SolrJsonFacetResponse>>(b).ok())
.unwrap_or_default();
let mut flat_facets = HashMap::new();
let nested_facets: HashMap<String, SolrJsonFacetResponse> = map
.drain()
.filter_map(|(key, value)| {
match serde_json::from_value::<SolrJsonFacetResponse>(value.clone()) {
Ok(v) => Some((key, v)),
Err(_) => {
flat_facets.insert(key, value);
None
}
}
})
.collect();
Ok(Self {
val,
count,
num_buckets,
missing: missing.map(Box::new),
all_buckets: all_buckets.map(Box::new),
buckets,
flat_facets,
nested_facets,
})
}
}