use std::borrow::Cow;
use serde::Serialize;
use serde_json::{Map, Value};
use crate::{QueryType, ToOpenSearchJson};
#[derive(Debug, Clone, Serialize)]
pub struct RangeQuery<'a> {
#[serde(borrow)]
pub field: Cow<'a, str>,
#[serde(skip_serializing_if = "Option::is_none")]
pub gte: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub gt: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lte: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lt: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub boost: Option<f64>,
}
impl<'a> RangeQuery<'a> {
pub fn new(field: impl Into<Cow<'a, str>>) -> Self {
Self {
field: field.into(),
gte: None,
gt: None,
lte: None,
lt: None,
boost: None,
}
}
pub fn gte<T: Into<Value>>(mut self, value: T) -> Self {
self.gte = Some(value.into());
self
}
pub fn gt<T: Into<Value>>(mut self, value: T) -> Self {
self.gt = Some(value.into());
self
}
pub fn lte<T: Into<Value>>(mut self, value: T) -> Self {
self.lte = Some(value.into());
self
}
pub fn lt<T: Into<Value>>(mut self, value: T) -> Self {
self.lt = Some(value.into());
self
}
pub fn boost(mut self, boost: f64) -> Self {
self.boost = Some(boost);
self
}
}
impl<'a> From<RangeQuery<'a>> for QueryType<'a> {
fn from(range_query: RangeQuery<'a>) -> Self {
QueryType::Range(range_query)
}
}
impl<'a> ToOpenSearchJson for RangeQuery<'a> {
fn to_json(&self) -> Value {
let mut range_obj = Map::new();
let mut field_obj = Map::new();
if let Some(ref gte) = self.gte {
field_obj.insert("gte".to_string(), gte.clone());
}
if let Some(ref gt) = self.gt {
field_obj.insert("gt".to_string(), gt.clone());
}
if let Some(ref lte) = self.lte {
field_obj.insert("lte".to_string(), lte.clone());
}
if let Some(ref lt) = self.lt {
field_obj.insert("lt".to_string(), lt.clone());
}
if let Some(boost) = self.boost {
field_obj.insert("boost".to_string(), boost.into());
}
range_obj.insert(self.field.to_string(), Value::Object(field_obj));
let mut result = Map::new();
result.insert("range".to_string(), Value::Object(range_obj));
Value::Object(result)
}
}
pub struct RangeQueryBuilder<'a> {
#[allow(dead_code)]
pub field: Cow<'a, str>,
pub gte: Option<Value>,
pub gt: Option<Value>,
pub lte: Option<Value>,
pub lt: Option<Value>,
pub boost: Option<f64>,
}
impl<'a> RangeQueryBuilder<'a> {
pub fn new(field: impl Into<Cow<'a, str>>) -> Self {
Self {
field: field.into(),
gte: None,
gt: None,
lte: None,
lt: None,
boost: None,
}
}
pub fn gte<T: Into<Value>>(&mut self, value: T) -> &mut Self {
self.gte = Some(value.into());
self
}
pub fn gt<T: Into<Value>>(&mut self, value: T) -> &mut Self {
self.gt = Some(value.into());
self
}
pub fn lte<T: Into<Value>>(&mut self, value: T) -> &mut Self {
self.lte = Some(value.into());
self
}
pub fn lt<T: Into<Value>>(&mut self, value: T) -> &mut Self {
self.lt = Some(value.into());
self
}
pub fn boost(&mut self, boost: f64) -> &mut Self {
self.boost = Some(boost);
self
}
pub fn build(self) -> RangeQuery<'a> {
RangeQuery {
field: self.field,
gte: self.gte,
gt: self.gt,
lte: self.lte,
lt: self.lt,
boost: self.boost,
}
}
}