use std::collections::{BTreeMap, HashMap};
use serde::{Deserialize, Serialize, Serializer};
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct JsonFacetComponent {
#[serde(rename = "json.facet", serialize_with = "json_facet_as_string")]
facet: HashMap<String, JsonFacetType>,
}
impl AsRef<JsonFacetComponent> for JsonFacetComponent {
fn as_ref(&self) -> &JsonFacetComponent {
self
}
}
impl From<&JsonFacetComponent> for JsonFacetComponent {
fn from(component: &JsonFacetComponent) -> Self {
component.clone()
}
}
impl JsonFacetComponent {
pub fn new() -> Self {
JsonFacetComponent {
facet: Default::default(),
}
}
pub fn facets<K: Into<String>, V: Into<JsonFacetType>, I: IntoIterator<Item = (K, V)>>(
mut self,
facets: I,
) -> Self {
self.facet = facets
.into_iter()
.map(|(k, v)| (k.into(), v.into()))
.collect();
self
}
}
impl Default for JsonFacetComponent {
fn default() -> Self {
JsonFacetComponent::new()
}
}
fn json_facet_as_string<S>(
facet: &HashMap<String, JsonFacetType>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let json_string = serde_json::to_string(facet).map_err(serde::ser::Error::custom)?;
serializer.serialize_str(&json_string)
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
pub enum JsonFacetType {
Terms(Box<JsonTermsFacet>),
Query(Box<JsonQueryFacet>),
Stat(JsonStatFacet),
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub enum JsonFacetSortDirection {
#[serde(rename = "asc")]
Asc,
#[serde(rename = "desc")]
Desc,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct JsonTermsFacet {
#[serde(rename = "type")]
type_: String,
field: String,
#[serde(skip_serializing_if = "Option::is_none")]
offset: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
limit: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
sort: Option<BTreeMap<String, JsonFacetSortDirection>>,
#[serde(skip_serializing_if = "Option::is_none")]
prelim_sort: Option<BTreeMap<String, JsonFacetSortDirection>>,
#[serde(skip_serializing_if = "Option::is_none")]
overrequest: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
refine: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
overrefine: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
mincount: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
missing: Option<bool>,
#[serde(rename = "numBuckets", skip_serializing_if = "Option::is_none")]
num_buckets: Option<bool>,
#[serde(rename = "allBuckets", skip_serializing_if = "Option::is_none")]
all_buckets: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
prefix: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
facet: Option<HashMap<String, JsonFacetType>>,
#[serde(skip_serializing_if = "Option::is_none")]
method: Option<JsonTermsFacetMethod>,
}
impl From<JsonTermsFacet> for JsonFacetType {
fn from(facet: JsonTermsFacet) -> Self {
JsonFacetType::Terms(Box::new(facet))
}
}
impl JsonTermsFacet {
pub fn new<S: Into<String>>(field: S) -> Self {
JsonTermsFacet {
type_: "terms".to_string(),
field: field.into(),
offset: None,
limit: None,
sort: None,
prelim_sort: None,
overrequest: None,
refine: None,
overrefine: None,
mincount: None,
missing: None,
num_buckets: None,
all_buckets: None,
prefix: None,
facet: None,
method: None,
}
}
pub fn offset<O: Into<Option<usize>>>(mut self, offset: O) -> Self {
self.offset = offset.into();
self
}
pub fn limit<O: Into<Option<usize>>>(mut self, limit: O) -> Self {
self.limit = limit.into();
self
}
pub fn sort<
K: Into<String>,
V: Into<JsonFacetSortDirection>,
I: IntoIterator<Item = (K, V)>,
O: Into<Option<I>>,
>(
mut self,
sort: O,
) -> Self {
self.sort = sort.into().map(|sort| {
sort.into_iter()
.map(|(k, v)| (k.into(), v.into()))
.collect()
});
self
}
pub fn prelim_sort<
K: Into<String>,
V: Into<JsonFacetSortDirection>,
I: IntoIterator<Item = (K, V)>,
O: Into<Option<I>>,
>(
mut self,
sort: O,
) -> Self {
self.prelim_sort = sort.into().map(|sort| {
sort.into_iter()
.map(|(k, v)| (k.into(), v.into()))
.collect()
});
self
}
pub fn overrequest<O: Into<Option<usize>>>(mut self, overrequest: O) -> Self {
self.overrequest = overrequest.into();
self
}
pub fn refine<O: Into<Option<bool>>>(mut self, refine: O) -> Self {
self.refine = refine.into();
self
}
pub fn overrefine<O: Into<Option<usize>>>(mut self, overrefine: O) -> Self {
self.overrefine = overrefine.into();
self
}
pub fn mincount<O: Into<Option<usize>>>(mut self, mincount: O) -> Self {
self.mincount = mincount.into();
self
}
pub fn missing<O: Into<Option<bool>>>(mut self, missing: O) -> Self {
self.missing = missing.into();
self
}
pub fn num_buckets<O: Into<Option<bool>>>(mut self, num_buckets: O) -> Self {
self.num_buckets = num_buckets.into();
self
}
pub fn all_buckets<O: Into<Option<bool>>>(mut self, all_buckets: O) -> Self {
self.all_buckets = all_buckets.into();
self
}
pub fn prefix<S: Into<String>, O: Into<Option<S>>>(mut self, prefix: O) -> Self {
self.prefix = prefix.into().map(|s| s.into());
self
}
pub fn facets<
K: Into<String>,
V: Into<JsonFacetType>,
I: IntoIterator<Item = (K, V)>,
O: Into<Option<I>>,
>(
mut self,
facets: O,
) -> Self {
self.facet = facets.into().map(|facets| {
facets
.into_iter()
.map(|(k, v)| (k.into(), v.into()))
.collect()
});
self
}
pub fn method<O: Into<Option<JsonTermsFacetMethod>>>(mut self, method: O) -> Self {
self.method = method.into();
self
}
}
#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq)]
pub enum JsonTermsFacetMethod {
#[serde(rename = "dv")]
DocValues,
#[serde(rename = "uif")]
UnInvertedField,
#[serde(rename = "dvhash")]
DocValuesHash,
#[serde(rename = "enum")]
Enum,
#[serde(rename = "stream")]
Stream,
#[serde(rename = "smart")]
Smart,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct JsonQueryFacet {
#[serde(rename = "type")]
type_: String,
#[serde(skip_serializing_if = "Option::is_none")]
q: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
limit: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
offset: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
sort: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
fq: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
facet: Option<HashMap<String, JsonFacetType>>,
}
impl From<JsonQueryFacet> for JsonFacetType {
fn from(facet: JsonQueryFacet) -> Self {
JsonFacetType::Query(Box::new(facet))
}
}
impl JsonQueryFacet {
pub fn new() -> Self {
JsonQueryFacet {
type_: "query".to_string(),
q: None,
limit: None,
offset: None,
sort: None,
fq: None,
facet: None,
}
}
pub fn q<S: Into<String>>(mut self, q: S) -> Self {
self.q = Some(q.into());
self
}
pub fn limit<O: Into<Option<usize>>>(mut self, limit: O) -> Self {
self.limit = limit.into();
self
}
pub fn offset<O: Into<Option<usize>>>(mut self, offset: O) -> Self {
self.offset = offset.into();
self
}
pub fn sort<S: Into<String>, O: Into<Option<S>>>(mut self, sort: O) -> Self {
self.sort = sort.into().map(|s| s.into());
self
}
pub fn fq<S: Into<String>, I: IntoIterator<Item = S>, O: Into<Option<I>>>(
mut self,
fq: O,
) -> Self {
self.fq = fq
.into()
.map(|fq| fq.into_iter().map(|s| s.into()).collect());
self
}
pub fn facets<
K: Into<String>,
V: Into<JsonFacetType>,
I: IntoIterator<Item = (K, V)>,
O: Into<Option<I>>,
>(
mut self,
facets: O,
) -> Self {
self.facet = facets.into().map(|facets| {
facets
.into_iter()
.map(|(k, v)| (k.into(), v.into()))
.collect()
});
self
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct JsonStatFacet(String);
impl From<JsonStatFacet> for JsonFacetType {
fn from(facet: JsonStatFacet) -> Self {
JsonFacetType::Stat(facet)
}
}
impl JsonStatFacet {
pub fn new<S: Into<String>>(stat: S) -> Self {
JsonStatFacet(stat.into())
}
}