use anyhow::bail;
use serde::{Deserialize, Serialize};
use super::FieldMappingEntry;
use crate::default_doc_mapper::default_mapper::Mode;
use crate::default_doc_mapper::QuickwitJsonOptions;
use crate::{DefaultDocMapper, SortByConfig};
#[derive(Serialize, Deserialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct DefaultDocMapperBuilder {
#[serde(default)]
pub store_source: bool,
#[serde(default)]
pub default_search_fields: Vec<String>,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub timestamp_field: Option<String>,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub sort_by: Option<SortByConfig>,
#[serde(default)]
pub field_mappings: Vec<FieldMappingEntry>,
#[serde(default)]
pub tag_fields: Vec<String>,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub demux_field: Option<String>,
#[serde(default)]
pub mode: ModeType,
#[serde(default)]
pub dynamic_mapping: Option<QuickwitJsonOptions>,
}
#[derive(Serialize, Deserialize, Copy, Clone, Debug, Eq, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum ModeType {
Lenient,
Strict,
Dynamic,
}
impl Default for ModeType {
fn default() -> Self {
ModeType::Lenient
}
}
#[cfg(test)]
impl Default for DefaultDocMapperBuilder {
fn default() -> Self {
serde_json::from_str("{}").unwrap()
}
}
impl DefaultDocMapperBuilder {
pub(crate) fn mode(&self) -> anyhow::Result<Mode> {
if self.mode != ModeType::Dynamic && self.dynamic_mapping.is_some() {
bail!(
"`dynamic_mapping` is only allowed with mode=dynamic. (Here mode=`{:?}`)",
self.mode
);
}
Ok(match self.mode {
ModeType::Lenient => Mode::Lenient,
ModeType::Strict => Mode::Strict,
ModeType::Dynamic => Mode::Dynamic(self.dynamic_mapping.clone().unwrap_or_default()),
})
}
pub fn try_build(self) -> anyhow::Result<DefaultDocMapper> {
self.try_into()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_mapper_builder_deserialize_from_empty_object() {
let default_mapper_builder: DefaultDocMapperBuilder =
serde_json::from_str::<DefaultDocMapperBuilder>("{}").unwrap();
assert!(default_mapper_builder.default_search_fields.is_empty());
assert!(default_mapper_builder.field_mappings.is_empty());
assert!(default_mapper_builder.tag_fields.is_empty());
assert_eq!(default_mapper_builder.mode, ModeType::Lenient);
assert!(default_mapper_builder.dynamic_mapping.is_none());
assert!(default_mapper_builder.demux_field.is_none());
assert!(default_mapper_builder.sort_by.is_none());
assert_eq!(default_mapper_builder.store_source, false);
assert!(default_mapper_builder.timestamp_field.is_none());
}
#[test]
fn test_default_mapper_builder_extra_field() {
assert!(
serde_json::from_str::<DefaultDocMapperBuilder>(r#"{"unknownfield": "blop"}"#).is_err()
);
}
}