Skip to main content

libverify_core/
registry.rs

1use crate::control::{Control, ControlId};
2
3/// Registry for dynamically collecting controls from multiple sources.
4///
5/// Built-in controls are pre-registered. Platform-specific verifiers
6/// can register additional controls (e.g. "jira-linkage").
7pub struct ControlRegistry {
8    controls: Vec<Box<dyn Control>>,
9}
10
11impl ControlRegistry {
12    /// Creates an empty registry.
13    pub fn new() -> Self {
14        Self {
15            controls: Vec::new(),
16        }
17    }
18
19    /// Creates a registry with all built-in controls (14 SLSA + 14 compliance).
20    pub fn builtin() -> Self {
21        let mut registry = Self::new();
22        registry.register_builtins();
23        registry
24    }
25
26    /// Registers a single control.
27    pub fn register(&mut self, control: Box<dyn Control>) {
28        self.controls.push(control);
29    }
30
31    /// Registers all built-in controls.
32    fn register_builtins(&mut self) {
33        use crate::controls;
34        self.controls.extend(controls::all_controls());
35    }
36
37    /// Returns a slice of all registered controls.
38    pub fn controls(&self) -> &[Box<dyn Control>] {
39        &self.controls
40    }
41
42    /// Returns the IDs of all registered controls.
43    pub fn control_ids(&self) -> Vec<ControlId> {
44        self.controls.iter().map(|c| c.id()).collect()
45    }
46
47    /// Returns the number of registered controls.
48    pub fn len(&self) -> usize {
49        self.controls.len()
50    }
51
52    /// Returns true if no controls are registered.
53    pub fn is_empty(&self) -> bool {
54        self.controls.is_empty()
55    }
56}
57
58impl Default for ControlRegistry {
59    fn default() -> Self {
60        Self::new()
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn builtin_registry_matches_all_count() {
70        use crate::control::builtin;
71        let registry = ControlRegistry::builtin();
72        assert_eq!(
73            registry.len(),
74            builtin::ALL.len(),
75            "registry must contain exactly one control per builtin::ALL entry"
76        );
77    }
78
79    #[test]
80    fn empty_registry() {
81        let registry = ControlRegistry::new();
82        assert!(registry.is_empty());
83    }
84}