use crate::runtime::goal::review::slice::{SliceReviewContext, SliceReviewOutcome};
#[allow(dead_code)]
pub trait ReviewPass: Send + Sync {
fn name(&self) -> &'static str;
fn run(&self, ctx: &SliceReviewContext) -> SliceReviewOutcome;
}
#[allow(dead_code)]
pub struct ReviewPassRegistry {
passes: Vec<Box<dyn ReviewPass>>,
}
#[allow(dead_code)]
impl ReviewPassRegistry {
pub fn new() -> Self {
Self { passes: Vec::new() }
}
pub fn register(&mut self, pass: Box<dyn ReviewPass>) {
self.passes.push(pass);
}
pub fn passes(&self) -> &[Box<dyn ReviewPass>] {
&self.passes
}
}
#[allow(dead_code)]
impl Default for ReviewPassRegistry {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
struct DummyPass(&'static str);
impl ReviewPass for DummyPass {
fn name(&self) -> &'static str {
self.0
}
fn run(&self, _ctx: &SliceReviewContext) -> SliceReviewOutcome {
SliceReviewOutcome {
passed: true,
review_path: None,
security_review_path: None,
feedback: None,
artifacts: Vec::new(),
slop_findings: Vec::new(),
}
}
}
#[test]
fn review_pass_registry_starts_empty() {
let registry = ReviewPassRegistry::new();
assert!(registry.passes().is_empty());
}
#[test]
fn review_pass_registry_registers_and_lists_in_order() {
let mut registry = ReviewPassRegistry::new();
registry.register(Box::new(DummyPass("architect")));
registry.register(Box::new(DummyPass("security")));
let passes = registry.passes();
assert_eq!(passes.len(), 2);
assert_eq!(passes[0].name(), "architect");
assert_eq!(passes[1].name(), "security");
}
}