use std::error::Error; use aderyn_driver::context::workspace_context::WorkspaceContext; use aderyn_driver::detector::ReusableDetector; use aderyn_driver::context::workspace_context::ASTNode; #[derive(Default)] pub struct {{detector_name_title_case}} { found_instances: Vec, } impl ReusableDetector for {{detector_name_title_case}} { fn detect( &mut self, context: &WorkspaceContext, using: &[ASTNode], within: &[ASTNode], ) -> Result<&[ASTNode], Box> { // Use the `context` to find nodes, then capture them as shown below // self.found_instances.push(my_ast_node.into()); Ok(&self.found_instances) } fn name(&self) -> String { "{{ detector_name_kebab_case }}".to_string() } } #[cfg(test)] mod {{detector_name_snake_case}}_tests { use crate::config_tests::tests_configuration; use super::{{detector_name_title_case}}; use aderyn_driver::context::workspace_context::WorkspaceContext; use aderyn_driver::detector::detector_test_helpers::load_contract; use aderyn_driver::detector::ReusableDetector; fn test_{{detector_name_snake_case}}_for( _contract_file: String, context: WorkspaceContext, mut detector: impl ReusableDetector, ) { // assert that the detector finds instances let results = detector.detect(&context, &Vec::new(), &Vec::new()).unwrap(); assert!(!results.is_empty()); } #[test] fn test_{{detector_name_snake_case}}() { let detector = {{detector_name_title_case}}::default(); let contracts = tests_configuration().get_contracts_for(detector.name()); for contract_file in contracts { let detector = {{detector_name_title_case}}::default(); let context = load_contract(&contract_file); test_{{detector_name_snake_case}}_for(contract_file, context, detector); } } }