term_guard/core/level.rs
1//! Validation severity levels.
2
3use serde::{Deserialize, Serialize};
4use std::fmt;
5
6/// The severity level of a validation check.
7///
8/// This enum represents different levels of importance for validation checks,
9/// allowing users to categorize issues by their impact on data quality.
10/// Levels are ordered by severity: Error > Warning > Info.
11///
12/// # Usage Guidelines
13///
14/// - **Error**: Use for critical data quality issues that prevent processing
15/// - Missing required fields
16/// - Primary key violations
17/// - Data integrity violations
18/// - Invalid data formats that break downstream systems
19///
20/// - **Warning**: Use for issues that should be investigated but don't block processing
21/// - Data quality below expected thresholds
22/// - Unusual patterns or outliers
23/// - Missing optional but recommended fields
24/// - Performance-impacting data issues
25///
26/// - **Info**: Use for informational metrics and observations
27/// - Data distribution statistics
28/// - Row counts and cardinality metrics
29/// - Performance benchmarks
30/// - Data profiling results
31///
32/// # Examples
33///
34/// ```rust
35/// use term_guard::core::{Check, Level, ConstraintOptions};
36/// use term_guard::constraints::Assertion;
37///
38/// // Critical validations that must pass
39/// let critical_check = Check::builder("required_fields")
40/// .level(Level::Error)
41/// .completeness("transaction_id", ConstraintOptions::new().with_threshold(1.0))
42/// .completeness("amount", ConstraintOptions::new().with_threshold(1.0))
43/// .build();
44///
45/// // Quality checks that flag potential issues
46/// let quality_check = Check::builder("data_quality")
47/// .level(Level::Warning)
48/// .completeness("email", ConstraintOptions::new().with_threshold(0.95))
49/// .validates_regex("phone", r"^\+?\d{3}-\d{3}-\d{4}$", 0.90)
50/// .build();
51///
52/// // Informational metrics
53/// let metrics_check = Check::builder("data_profile")
54/// .level(Level::Info)
55/// .has_size(Assertion::GreaterThan(0.0))
56/// .has_mean("order_value", Assertion::Between(10.0, 1000.0))
57/// .build();
58/// ```
59///
60/// # Comparison
61///
62/// ```rust
63/// use term_guard::core::Level;
64///
65/// let critical_level = Level::Error;
66/// let warning_level = Level::Warning;
67/// let info_level = Level::Info;
68///
69/// assert!(critical_level > warning_level);
70/// assert!(warning_level > info_level);
71/// ```
72#[derive(
73 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default,
74)]
75#[serde(rename_all = "lowercase")]
76pub enum Level {
77 /// Informational level - Used for metrics and non-critical observations
78 Info = 0,
79 /// Warning level - Indicates potential issues that should be reviewed
80 #[default]
81 Warning = 1,
82 /// Error level - Indicates critical data quality issues that must be addressed
83 Error = 2,
84}
85
86impl Level {
87 /// Returns the string representation of the level.
88 pub fn as_str(&self) -> &'static str {
89 match self {
90 Level::Info => "info",
91 Level::Warning => "warning",
92 Level::Error => "error",
93 }
94 }
95
96 /// Checks if this level is at least as severe as another level.
97 ///
98 /// # Examples
99 ///
100 /// ```rust
101 /// use term_guard::core::Level;
102 ///
103 /// assert!(Level::Error.is_at_least(Level::Warning));
104 /// assert!(Level::Warning.is_at_least(Level::Warning));
105 /// assert!(!Level::Info.is_at_least(Level::Error));
106 /// ```
107 pub fn is_at_least(&self, other: Level) -> bool {
108 *self >= other
109 }
110}
111
112impl fmt::Display for Level {
113 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
114 write!(f, "{}", self.as_str())
115 }
116}
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121
122 #[test]
123 fn test_level_ordering() {
124 assert!(Level::Error > Level::Warning);
125 assert!(Level::Warning > Level::Info);
126 assert!(Level::Error > Level::Info);
127 }
128
129 #[test]
130 fn test_level_display() {
131 assert_eq!(Level::Info.to_string(), "info");
132 assert_eq!(Level::Warning.to_string(), "warning");
133 assert_eq!(Level::Error.to_string(), "error");
134 }
135
136 #[test]
137 fn test_level_is_at_least() {
138 assert!(Level::Error.is_at_least(Level::Info));
139 assert!(Level::Error.is_at_least(Level::Warning));
140 assert!(Level::Error.is_at_least(Level::Error));
141 assert!(Level::Warning.is_at_least(Level::Info));
142 assert!(Level::Warning.is_at_least(Level::Warning));
143 assert!(!Level::Warning.is_at_least(Level::Error));
144 assert!(Level::Info.is_at_least(Level::Info));
145 assert!(!Level::Info.is_at_least(Level::Warning));
146 assert!(!Level::Info.is_at_least(Level::Error));
147 }
148
149 #[test]
150 fn test_level_serde() {
151 let json = serde_json::to_string(&Level::Error).unwrap();
152 assert_eq!(json, "\"error\"");
153
154 let level: Level = serde_json::from_str("\"warning\"").unwrap();
155 assert_eq!(level, Level::Warning);
156 }
157}