use libfse::{FseMap, FseOpcode, Rule};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let rules = vec![
Rule { pattern: b"DROP TABLE".to_vec(), opcode: FseOpcode::Reject(0) },
Rule { pattern: b"SELECT *".to_vec(), opcode: FseOpcode::Record(1) },
Rule { pattern: b"--".to_vec(), opcode: FseOpcode::Ignore },
];
let map = FseMap::compile(rules)?;
let mut cursor = map.new_cursor()?;
println!("Scanning: 'SELECT * FROM users -- safe query'");
let summary = map.scan_with_cursor(
&mut cursor,
b"SELECT * FROM users -- safe query",
)?;
println!(
" → ok | match states: {} | rules fired: {} | distinct rules: {}",
summary.match_states_seen, summary.pattern_hits, summary.rules_recorded
);
println!("\nScanning: 'DROP TABLE users'");
let result = map.scan_with_cursor(&mut cursor, b"DROP TABLE users");
match result {
Err(libfse::scanner::Violation::PolicyReject { rule_id, .. }) => {
println!(" → REJECTED (rule_id={})", rule_id);
}
Err(libfse::scanner::Violation::IntegrityError { details, .. }) => {
println!(" → INTEGRITY ERROR: {}", details);
}
Ok(_) => println!(" → ok (unexpected)"),
}
let mut cursor2 = map.new_cursor()?;
println!("\nFresh cursor. Scanning safe input again:");
let summary2 = map.scan_with_cursor(&mut cursor2, b"SELECT * FROM orders")?;
println!(" → ok | rules fired: {}", summary2.rules_recorded);
Ok(())
}