use std::path::PathBuf;
use anyhow::{Result, bail};
use serde::{Deserialize, Serialize};
use crate::schema::intermediate::IntermediateFunctionsConfig;
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct FunctionsSettings {
pub module_dir: Option<PathBuf>,
pub dlq_store: Option<String>,
}
impl FunctionsSettings {
#[must_use]
pub const fn is_configured(&self) -> bool {
self.module_dir.is_some() || self.dlq_store.is_some()
}
pub fn reconcile(
&self,
document: Option<IntermediateFunctionsConfig>,
) -> Result<Option<IntermediateFunctionsConfig>> {
if !self.is_configured() {
return Ok(document);
}
let from_config = IntermediateFunctionsConfig {
module_dir: self.module_dir.clone(),
dlq_store: self.dlq_store.clone(),
};
let Some(from_document) = document else {
return Ok(Some(from_config));
};
let differing = if from_config.module_dir == from_document.module_dir {
(from_config.dlq_store != from_document.dlq_store).then_some("dlq_store")
} else {
Some("module_dir")
};
if let Some(key) = differing {
bail!(
"fraiseql.toml [functions] and schema.json functions_config disagree on \
`{key}`.\n fraiseql.toml [functions]: {}\n schema.json functions_config: \
{}\nDeclare the functions settings once, in fraiseql.toml.",
serde_json::to_string(&from_config).unwrap_or_default(),
serde_json::to_string(&from_document).unwrap_or_default(),
);
}
Ok(Some(from_config))
}
}