use serde::{Deserialize, Serialize};
use vantage_core::{Result, error};
use vantage_vista::VistaSpec;
pub(crate) mod pipeline;
pub use pipeline::DriverBlockArgs;
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct MongoTableExtras {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub mongo: Option<MongoBlock>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct MongoBlock {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub collection: Option<String>,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub view: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub pipeline: Option<Vec<serde_json::Value>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub rhai: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub modify: Option<String>,
#[serde(skip)]
pub args: Vec<(String, String)>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct MongoColumnExtras {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub mongo: Option<MongoColumnBlock>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct MongoColumnBlock {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub field: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub nested_path: Option<String>,
}
impl MongoColumnBlock {
pub fn resolved_path(&self, column_name: &str) -> Result<Option<Vec<String>>> {
if let Some(p) = &self.nested_path {
let segments: Vec<String> = p.split('.').map(str::to_string).collect();
if segments.iter().any(String::is_empty) {
return Err(error!(
"nested_path must not be empty or contain empty segments",
column = column_name.to_string(),
nested_path = p.clone()
));
}
return Ok(Some(segments));
}
if let Some(f) = &self.field {
if f.is_empty() {
return Err(error!(
"field must not be empty",
column = column_name.to_string()
));
}
return Ok(Some(vec![f.clone()]));
}
Ok(None)
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct MongoReferenceExtras {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub mongo: Option<MongoRefBlock>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct MongoRefBlock {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub rhai: Option<String>,
}
pub type MongoVistaSpec = VistaSpec<MongoTableExtras, MongoColumnExtras, MongoReferenceExtras>;