1#![warn(missing_docs)]
56#![warn(unsafe_code)]
57#![warn(clippy::all)]
58#![warn(clippy::pedantic)]
59#![warn(clippy::suspicious)]
60#![allow(clippy::module_name_repetitions)]
61#![allow(clippy::similar_names)]
62#![allow(clippy::too_many_lines)]
63#![allow(clippy::doc_markdown)]
64#![allow(clippy::missing_errors_doc)]
65#![allow(clippy::missing_panics_doc)]
66#![allow(clippy::struct_excessive_bools)]
67#![allow(clippy::fn_params_excessive_bools)]
68#![allow(clippy::too_many_arguments)]
69#![allow(clippy::type_complexity)]
70#![cfg_attr(docsrs, feature(doc_cfg))]
71#![cfg_attr(test, allow(clippy::unwrap_used))]
73#![cfg_attr(test, allow(clippy::expect_used))]
74
75#[cfg(all(feature = "mimalloc", not(feature = "jemalloc")))]
77#[global_allocator]
78static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc;
79
80#[cfg(all(feature = "jemalloc", not(feature = "mimalloc")))]
81#[global_allocator]
82static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
83
84pub mod core {
86 pub mod arena_analysis;
89 pub mod ast;
90 pub mod config;
91 pub mod coverage_discovery;
92 pub mod dependency;
93 pub mod errors;
94 pub mod featureset;
95 pub mod file_utils;
96 pub mod interned_entities;
97 pub mod interning;
98 pub mod partitioning;
99 pub mod pipeline;
100 pub mod scoring;
101
102 pub use ast::service as ast_service;
104 pub use ast::utils as ast_utils;
105 pub use ast::visitor as unified_visitor;
106
107 pub use scoring::bayesian;
109}
110
111pub mod detectors {
113 pub mod bundled;
116 pub mod cohesion;
117 pub mod complexity;
118 pub mod coverage;
119 pub mod graph;
120 pub mod lsh;
121 pub mod refactoring;
122 pub mod structure;
123}
124
125#[path = "lang/mod.rs"]
127pub mod lang;
128
129pub mod io {
131 pub mod cache;
134 pub mod reports;
135}
136
137pub mod oracle;
139
140pub mod doc_audit;
142
143pub mod api {
145 pub mod config_types;
148 pub mod engine;
149 pub mod results;
150}
151
152pub use crate::core::pipeline::AnalysisResults;
154pub use api::config_types::AnalysisConfig;
155pub use api::engine::ValknutEngine;
156pub use core::errors::{Result, ValknutError, ValknutResultExt};
157
158#[cfg(test)]
159mod test_coverage_integration;
160
161pub const VERSION: &str = env!("CARGO_PKG_VERSION");
163
164pub mod features {
166 pub const fn has_simd() -> bool {
170 cfg!(feature = "simd")
171 }
172
173 pub const fn has_parallel() -> bool {
175 cfg!(feature = "parallel")
176 }
177}
178
179#[cfg(test)]
180mod lib_exports_tests {
181 use super::*;
182
183 #[test]
184 fn version_constant_is_non_empty() {
185 assert!(
186 !VERSION.trim().is_empty(),
187 "VERSION should contain the crate version at build time"
188 );
189 }
190
191 #[test]
192 fn feature_flags_match_cfg_settings() {
193 assert_eq!(
194 features::has_simd(),
195 cfg!(feature = "simd"),
196 "has_simd should mirror the compile-time cfg flag"
197 );
198 assert_eq!(
199 features::has_parallel(),
200 cfg!(feature = "parallel"),
201 "has_parallel should mirror the compile-time cfg flag"
202 );
203 }
204
205 #[test]
206 fn analysis_config_reexports_support_builder_flows() {
207 let config = AnalysisConfig::default()
208 .disable_all_modules()
209 .with_language("rust")
210 .enable_all_modules()
211 .with_confidence_threshold(0.6)
212 .exclude_pattern("target/generated/*");
213
214 assert!(config.modules.complexity);
215 assert!(config.modules.coverage);
216 assert!(
217 config.languages.enabled.iter().any(|lang| lang == "rust"),
218 "builder should append requested language"
219 );
220 assert!(
221 config
222 .files
223 .exclude_patterns
224 .iter()
225 .any(|pattern| pattern.contains("generated")),
226 "exclude pattern from builder should be retained"
227 );
228 assert!(
229 config.validate().is_ok(),
230 "valid builder configuration should pass validation"
231 );
232
233 let essentials = AnalysisConfig::default().essential_modules_only();
234 assert!(essentials.modules.complexity);
235 assert!(!essentials.modules.dependencies);
236 assert!(!essentials.modules.coverage);
237
238 let invalid = AnalysisConfig::default().with_confidence_threshold(1.5);
239 assert!(
240 invalid.validate().is_err(),
241 "confidence thresholds outside 0.0-1.0 should be rejected"
242 );
243 }
244}