SNAPKITTYWEST's picture
push from SNAPKITTYWEST/hyperkitty-constraint-dsl
224e773 verified
Raw
History Blame Contribute Delete
1.55 kB
//! AST validation and dangerous pattern detection
use super::nodes::AstNode;
use crate::Result;
use hyperkitty_core::Error;
/// Validate AST structure before construction
pub fn validate(nodes: &[AstNode], edges: &[(usize, usize)]) -> Result<()> {
// Check for dangerous patterns
for &(from_idx, to_idx) in edges {
if from_idx >= nodes.len() || to_idx >= nodes.len() {
return Err(Error::InvalidAST("Edge index out of bounds".to_string()));
}
let from = &nodes[from_idx];
let to = &nodes[to_idx];
if super::weights::has_dangerous_pattern(from, to) {
return Err(Error::InvalidAST(format!(
"Dangerous pattern: {} → {}",
from.label, to.label
)));
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use super::super::nodes::NodeType;
#[test]
fn valid_ast() {
let nodes = vec![
AstNode::new(NodeType::Intent, "route"),
AstNode::new(NodeType::Word, "hello"),
];
let edges = vec![(0, 1)]; // structural → payload (OK)
assert!(validate(&nodes, &edges).is_ok());
}
#[test]
fn invalid_ast_dangerous() {
let nodes = vec![
AstNode::new(NodeType::Word, "hello"),
AstNode::new(NodeType::Intent, "route"),
];
let edges = vec![(0, 1)]; // payload → structural (BLOCKED)
assert!(validate(&nodes, &edges).is_err());
}
}