use std::{borrow::Cow, fmt::Display};
use serde::Serialize;
use serde_json::Value;
use crate::{QueryType, ToOpenSearchJson};
#[derive(Debug, Clone, Serialize, Default)]
#[serde(rename_all = "UPPERCASE")]
pub enum RegexpQueryFlags {
All,
Anystring,
Complement,
Empty,
Intersection,
Interval,
#[default]
None,
}
impl RegexpQueryFlags {
pub fn all() -> Vec<Self> {
vec![Self::All]
}
}
impl Display for RegexpQueryFlags {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
RegexpQueryFlags::All => write!(f, "ALL"),
RegexpQueryFlags::Anystring => write!(f, "ANYSTRING"),
RegexpQueryFlags::Complement => write!(f, "COMPLEMENT"),
RegexpQueryFlags::Empty => write!(f, "EMPTY"),
RegexpQueryFlags::Intersection => write!(f, "INTERSECTION"),
RegexpQueryFlags::Interval => write!(f, "INTERVAL"),
RegexpQueryFlags::None => write!(f, "NONE"),
}
}
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct RegexpQuery<'a> {
#[serde(borrow)]
pub field: Cow<'a, str>,
#[serde(borrow)]
pub value: Cow<'a, str>,
#[serde(borrow)]
pub flags: Option<Cow<'a, [RegexpQueryFlags]>>,
}
impl<'a> RegexpQuery<'a> {
pub fn new(field: impl Into<Cow<'a, str>>, value: impl Into<Cow<'a, str>>) -> Self {
Self {
field: field.into(),
value: value.into(),
flags: None,
}
}
pub fn flags(mut self, flags: Cow<'a, [RegexpQueryFlags]>) -> Self {
self.flags = Some(flags);
self
}
pub fn to_owned(&self) -> RegexpQuery<'static> {
RegexpQuery {
field: Cow::Owned(self.field.to_string()),
value: Cow::Owned(self.value.to_string()),
flags: self.flags.as_ref().map(|f| Cow::Owned(f.to_vec())),
}
}
}
impl<'a> From<RegexpQuery<'a>> for QueryType<'a> {
fn from(regexp_query: RegexpQuery<'a>) -> Self {
QueryType::Regexp(regexp_query)
}
}
impl<'a> ToOpenSearchJson for RegexpQuery<'a> {
fn to_json(&self) -> Value {
let mut json = serde_json::json!({
"regexp": {
self.field.as_ref(): {
"value": self.value.as_ref(),
}
}
});
if let Some(flags) = self.flags.as_ref()
&& !flags.is_empty()
{
json["regexp"][self.field.as_ref()]["flags"] = Value::String(
flags
.iter()
.map(ToString::to_string)
.collect::<Vec<_>>()
.join("|"),
);
}
json
}
}