use std::collections::HashSet;
use crate::cop::Cop;
use crate::cops;
pub struct CopRegistry {
cops: Vec<Box<dyn Cop>>,
disabled: HashSet<String>,
}
impl CopRegistry {
pub fn new() -> Self {
Self {
cops: cops::all_cops(),
disabled: HashSet::new(),
}
}
pub fn disable(&mut self, name: &str) {
self.disabled.insert(name.to_string());
}
pub fn enable(&mut self, name: &str) {
self.disabled.remove(name);
}
pub fn enabled_cops(&self) -> Vec<&dyn Cop> {
self.cops
.iter()
.filter(|cop| !self.disabled.contains(cop.name()))
.map(|cop| cop.as_ref())
.collect()
}
pub fn cop_names(&self) -> Vec<&str> {
self.cops.iter().map(|cop| cop.name()).collect()
}
pub fn is_enabled(&self, name: &str) -> bool {
!self.disabled.contains(name)
}
pub fn total_count(&self) -> usize {
self.cops.len()
}
pub fn enabled_count(&self) -> usize {
self.cops.len() - self.disabled.len()
}
}
impl Default for CopRegistry {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_registry_has_all_cops() {
let registry = CopRegistry::new();
assert!(registry.total_count() > 0);
assert_eq!(registry.enabled_count(), registry.total_count());
}
#[test]
fn test_disable_cop() {
let mut registry = CopRegistry::new();
let initial_count = registry.enabled_count();
registry.disable("Layout/TrailingWhitespace");
assert_eq!(registry.enabled_count(), initial_count - 1);
assert!(!registry.is_enabled("Layout/TrailingWhitespace"));
}
#[test]
fn test_enable_cop() {
let mut registry = CopRegistry::new();
registry.disable("Layout/TrailingWhitespace");
assert!(!registry.is_enabled("Layout/TrailingWhitespace"));
registry.enable("Layout/TrailingWhitespace");
assert!(registry.is_enabled("Layout/TrailingWhitespace"));
}
#[test]
fn test_enabled_cops_filter() {
let mut registry = CopRegistry::new();
let total = registry.total_count();
registry.disable("Layout/TrailingWhitespace");
registry.disable("Style/StringLiterals");
let enabled = registry.enabled_cops();
assert_eq!(enabled.len(), total - 2);
for cop in enabled {
assert!(cop.name() != "Layout/TrailingWhitespace");
assert!(cop.name() != "Style/StringLiterals");
}
}
#[test]
fn test_cop_names_returns_all() {
let registry = CopRegistry::new();
let names = registry.cop_names();
assert_eq!(names.len(), registry.total_count());
assert!(names.contains(&"Layout/TrailingWhitespace"));
assert!(names.contains(&"Style/StringLiterals"));
}
#[test]
fn test_disable_nonexistent_cop() {
let mut registry = CopRegistry::new();
let initial_count = registry.enabled_count();
registry.disable("NonExistent/Cop");
assert_eq!(registry.enabled_count(), initial_count - 1);
}
}