ass_core/analysis/styles/validation/
conflict.rs1use alloc::{format, string::String, string::ToString, vec, vec::Vec};
8use core::fmt;
9
10use super::ValidationSeverity;
11
12#[derive(Debug, Clone)]
14pub struct StyleConflict<'a> {
15 pub styles: Vec<&'a str>,
17 pub conflict_type: ConflictType,
19 pub description: String,
21 pub severity: ValidationSeverity,
23}
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27pub enum ConflictType {
28 DuplicateName,
30 CircularInheritance,
32 PropertyConflict,
34 MissingReference,
36}
37
38impl<'a> StyleConflict<'a> {
39 #[must_use]
41 pub fn new(
42 conflict_type: ConflictType,
43 styles: Vec<&'a str>,
44 description: &str,
45 severity: ValidationSeverity,
46 ) -> Self {
47 Self {
48 styles,
49 conflict_type,
50 description: description.to_string(),
51 severity,
52 }
53 }
54
55 #[must_use]
57 pub fn duplicate_name(style_names: Vec<&'a str>) -> Self {
58 let description = format!("Duplicate style names found: {style_names:?}");
59 Self::new(
60 ConflictType::DuplicateName,
61 style_names,
62 &description,
63 ValidationSeverity::Error,
64 )
65 }
66
67 #[must_use]
69 pub fn circular_inheritance(cycle_styles: Vec<&'a str>) -> Self {
70 let description = format!("Circular inheritance detected: {cycle_styles:?}");
71 Self::new(
72 ConflictType::CircularInheritance,
73 cycle_styles,
74 &description,
75 ValidationSeverity::Error,
76 )
77 }
78
79 #[must_use]
81 pub fn missing_reference(referencing_style: &'a str, missing_style: &'a str) -> Self {
82 let description =
83 format!("Style '{referencing_style}' references non-existent style '{missing_style}'");
84 Self::new(
85 ConflictType::MissingReference,
86 vec![referencing_style],
87 &description,
88 ValidationSeverity::Error,
89 )
90 }
91
92 #[must_use]
94 pub fn missing_parent(style_name: &'a str, parent_name: &'a str) -> Self {
95 let description =
96 format!("Style '{style_name}' inherits from non-existent parent '{parent_name}'");
97 Self::new(
98 ConflictType::MissingReference,
99 vec![style_name],
100 &description,
101 ValidationSeverity::Warning,
102 )
103 }
104}
105
106impl fmt::Display for ConflictType {
107 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108 match self {
109 Self::DuplicateName => write!(f, "duplicate_name"),
110 Self::CircularInheritance => write!(f, "circular_inheritance"),
111 Self::PropertyConflict => write!(f, "property_conflict"),
112 Self::MissingReference => write!(f, "missing_reference"),
113 }
114 }
115}