#[cfg(test)]
mod tests;
use crate::diagnostics::{SchemaError, span_error};
pub(super) fn validate_procedure_no_idempotency_attribute(
procedure: &cratestack_core::Procedure,
) -> Result<(), SchemaError> {
let matches: Vec<&cratestack_core::Attribute> = procedure
.attributes
.iter()
.filter(|a| a.raw == "@no_idempotency" || a.raw.starts_with("@no_idempotency("))
.collect();
if matches.is_empty() {
return Ok(());
}
if matches.len() > 1 {
return Err(span_error(
format!(
"procedure `{}` declares more than one @no_idempotency attribute",
procedure.name,
),
matches[1].span,
));
}
let attr = matches[0];
if attr.raw != "@no_idempotency" {
return Err(span_error(
format!(
"procedure `{}` @no_idempotency does not take any arguments — it is a bare \
opt-out marker, and a value like `@no_idempotency(false)` would read as \
re-enabling idempotency while doing the opposite",
procedure.name,
),
attr.span,
));
}
Ok(())
}