Skip to main content

ferrous_forge/validation/
violation.rs

1//! Violation types and reporting
2
3use serde::{Deserialize, Serialize};
4use std::path::PathBuf;
5
6/// Types of violations that can be detected
7#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
8pub enum ViolationType {
9    /// Underscore parameter or let assignment bandaid
10    UnderscoreBandaid,
11    /// Wrong Rust edition (locked by project config)
12    WrongEdition,
13    /// File exceeds size limit
14    FileTooLarge,
15    /// Function exceeds size limit
16    FunctionTooLarge,
17    /// Line exceeds length limit
18    LineTooLong,
19    /// Use of `.unwrap()` or `.expect()` in production code
20    UnwrapInProduction,
21    /// Missing documentation
22    MissingDocs,
23    /// Missing required dependencies
24    MissingDependencies,
25    /// Rust version too old (locked by project config)
26    OldRustVersion,
27    /// A project configuration value is locked and was violated
28    LockedSetting,
29    /// Module-level //! documentation is missing
30    MissingModuleDoc,
31    /// Cargo.toml is missing [lints.rustdoc] configuration
32    MissingDocConfig,
33    /// Hardcoded version string found (should use env!("CARGO_PKG_VERSION"))
34    HardcodedVersion,
35    /// Missing changelog entry for current version
36    MissingChangelogEntry,
37    /// Changelog does not follow Keep a Changelog format
38    InvalidChangelogFormat,
39}
40
41/// Severity level of a violation
42#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
43pub enum Severity {
44    /// Violation that prevents code from compiling
45    Error,
46    /// Violation that should be fixed but doesn't break compilation
47    Warning,
48}
49
50/// A single standards violation
51#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
52pub struct Violation {
53    /// Type of violation
54    pub violation_type: ViolationType,
55    /// File where violation occurred
56    pub file: PathBuf,
57    /// Line number (1-based for display)
58    pub line: usize,
59    /// Human-readable message
60    pub message: String,
61    /// Severity of the violation
62    pub severity: Severity,
63}
64
65impl Violation {
66    /// Create a new violation
67    pub fn new(
68        violation_type: ViolationType,
69        file: PathBuf,
70        line: usize,
71        message: String,
72        severity: Severity,
73    ) -> Self {
74        Self {
75            violation_type,
76            file,
77            line,
78            message,
79            severity,
80        }
81    }
82
83    /// Returns true if this violation represents a locked setting (edition/version/config lock)
84    pub fn is_locked_setting(&self) -> bool {
85        matches!(
86            self.violation_type,
87            ViolationType::WrongEdition
88                | ViolationType::OldRustVersion
89                | ViolationType::LockedSetting
90        )
91    }
92}