use std::borrow::Cow;
use serde::Serialize;
use serde_json::{Map, Value};
use crate::{QueryType, ToOpenSearchJson};
#[derive(Debug, Clone, Serialize)]
pub struct MatchQuery<'a> {
#[serde(borrow)]
pub field: Cow<'a, str>,
#[serde(borrow)]
pub query: Cow<'a, str>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(borrow)]
pub operator: Option<Cow<'a, str>>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(borrow)]
pub fuzziness: Option<Cow<'a, str>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub boost: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(borrow)]
pub minimum_should_match: Option<Cow<'a, str>>,
}
impl<'a> MatchQuery<'a> {
pub fn new(field: impl Into<Cow<'a, str>>, query: impl Into<Cow<'a, str>>) -> Self {
Self {
field: field.into(),
query: query.into(),
operator: None,
fuzziness: None,
boost: None,
minimum_should_match: None,
}
}
pub fn operator(mut self, operator: impl Into<Cow<'a, str>>) -> Self {
self.operator = Some(operator.into());
self
}
pub fn fuzziness(mut self, fuzziness: impl Into<Cow<'a, str>>) -> Self {
self.fuzziness = Some(fuzziness.into());
self
}
pub fn boost(mut self, boost: f64) -> Self {
self.boost = Some(boost);
self
}
pub fn minimum_should_match(mut self, minimum_should_match: impl Into<Cow<'a, str>>) -> Self {
self.minimum_should_match = Some(minimum_should_match.into());
self
}
}
impl<'a> From<MatchQuery<'a>> for QueryType<'a> {
fn from(match_query: MatchQuery<'a>) -> Self {
QueryType::Match(match_query)
}
}
impl<'a> ToOpenSearchJson for MatchQuery<'a> {
fn to_json(&self) -> Value {
let mut result = Map::new();
let mut match_obj = Map::new();
let has_options = self.operator.is_some()
|| self.fuzziness.is_some()
|| self.boost.is_some()
|| self.minimum_should_match.is_some();
if has_options {
let mut field_obj = Map::new();
field_obj.insert("query".to_string(), Value::String(self.query.to_string()));
if let Some(ref operator) = self.operator {
field_obj.insert("operator".to_string(), Value::String(operator.to_string()));
}
if let Some(ref fuzziness) = self.fuzziness {
field_obj.insert(
"fuzziness".to_string(),
Value::String(fuzziness.to_string()),
);
}
if let Some(boost) = self.boost {
field_obj.insert("boost".to_string(), boost.into());
}
if let Some(ref minimum_should_match) = self.minimum_should_match {
field_obj.insert(
"minimum_should_match".to_string(),
Value::String(minimum_should_match.to_string()),
);
}
match_obj.insert(self.field.to_string(), Value::Object(field_obj));
} else {
match_obj.insert(
self.field.to_string(),
Value::String(self.query.to_string()),
);
}
result.insert("match".to_string(), Value::Object(match_obj));
Value::Object(result)
}
}