ass_editor/utils/validator/issue.rs
1//! Validation severity levels and individual issue representation.
2//!
3//! Defines `ValidationSeverity` and `ValidationIssue`, the building blocks
4//! used to describe problems found while validating editor documents.
5
6#[cfg(not(feature = "std"))]
7use alloc::string::String;
8
9/// Validation severity levels
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
11pub enum ValidationSeverity {
12 /// Informational message
13 #[default]
14 Info,
15 /// Warning that doesn't prevent script execution
16 Warning,
17 /// Error that may cause rendering issues
18 Error,
19 /// Critical error that prevents script execution
20 Critical,
21}
22
23/// A validation issue found in the document
24#[derive(Debug, Clone, PartialEq, Eq)]
25pub struct ValidationIssue {
26 /// Severity of the issue
27 pub severity: ValidationSeverity,
28
29 /// Line number where the issue occurs (1-indexed)
30 pub line: Option<usize>,
31
32 /// Column number where the issue occurs (1-indexed)
33 pub column: Option<usize>,
34
35 /// Human-readable description of the issue
36 pub message: String,
37
38 /// Rule or check that generated this issue
39 pub rule: String,
40
41 /// Suggested fix for the issue (if available)
42 pub suggestion: Option<String>,
43}
44
45impl ValidationIssue {
46 /// Create a new validation issue
47 ///
48 /// # Examples
49 ///
50 /// ```
51 /// use ass_editor::utils::validator::{ValidationIssue, ValidationSeverity};
52 ///
53 /// let issue = ValidationIssue::new(
54 /// ValidationSeverity::Warning,
55 /// "Missing subtitle end time".to_string(),
56 /// "timing_check".to_string()
57 /// )
58 /// .at_location(10, 25)
59 /// .with_suggestion("Add explicit end time".to_string());
60 ///
61 /// assert_eq!(issue.line, Some(10));
62 /// assert_eq!(issue.column, Some(25));
63 /// assert!(!issue.is_error());
64 /// ```
65 pub fn new(severity: ValidationSeverity, message: String, rule: String) -> Self {
66 Self {
67 severity,
68 line: None,
69 column: None,
70 message,
71 rule,
72 suggestion: None,
73 }
74 }
75
76 /// Set the location of this issue
77 #[must_use]
78 pub fn at_location(mut self, line: usize, column: usize) -> Self {
79 self.line = Some(line);
80 self.column = Some(column);
81 self
82 }
83
84 /// Add a suggestion for fixing this issue
85 #[must_use]
86 pub fn with_suggestion(mut self, suggestion: String) -> Self {
87 self.suggestion = Some(suggestion);
88 self
89 }
90
91 /// Check if this is an error or critical issue
92 #[must_use]
93 pub const fn is_error(&self) -> bool {
94 matches!(
95 self.severity,
96 ValidationSeverity::Error | ValidationSeverity::Critical
97 )
98 }
99
100 /// Check if this is a warning or higher
101 #[must_use]
102 pub const fn is_warning_or_higher(&self) -> bool {
103 matches!(
104 self.severity,
105 ValidationSeverity::Warning | ValidationSeverity::Error | ValidationSeverity::Critical
106 )
107 }
108}