1use crate::{
8 aim::{PrintMode, Writer, WriterLike},
9 expressions::Expression,
10 values::Value,
11};
12use std::{
13 fmt,
14 sync::Arc,
15};
16
17#[derive(Debug, Clone, PartialEq, Eq)]
22pub enum Errata {
23 One { reason: Arc<str> },
25 Two { reason: Arc<str>, formula: Arc<str> },
27 Three {
29 reason: Arc<str>,
30 formula: Arc<str>,
31 location: Arc<str>,
32 },
33 Critical { reason: Arc<str>, formula: Arc<str> },
35}
36
37#[derive(Debug)]
41pub struct CriticalError {
42 pub reason: Arc<str>,
43}
44
45impl std::fmt::Display for CriticalError {
46 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47 write!(f, "{}", self.reason)
48 }
49}
50
51impl std::error::Error for CriticalError {}
52
53impl CriticalError {
54 pub fn new(reason: Arc<str>) -> Self {
55 Self { reason }
56 }
57}
58
59impl Errata {
60 pub fn new_reason(reason: Arc<str>) -> Value {
62 Value::Errata(Errata::One { reason })
63 }
64
65 pub fn new_reason_formula(reason: Arc<str>, formula: Arc<str>) -> Value {
67 Value::Errata(Errata::Two { reason, formula })
68 }
69
70 pub fn new_reason_formula_location(reason: Arc<str>, formula: Arc<str>, location: Arc<str>) -> Value {
72 Value::Errata(Errata::Three {
73 reason,
74 formula,
75 location,
76 })
77 }
78
79 pub fn new_expression(reason: Arc<str>, expression: Arc<str>) -> Expression {
81 Expression::Errata(Errata::Two {
82 reason,
83 formula: expression,
84 })
85 }
86
87 pub fn new_expression_location(
89 reason: Arc<str>,
90 expression: Arc<str>,
91 location: Arc<str>,
92 ) -> Expression {
93 Expression::Errata(Errata::Three {
94 reason,
95 formula: expression,
96 location,
97 })
98 }
99
100 pub fn reason(&self) -> Arc<str> {
102 match self {
103 Errata::Three {
104 reason,
105 formula: _,
106 location: _,
107 } => reason.clone(),
108 Errata::Two { reason, formula: _ } => reason.clone(),
109 Errata::One { reason } => reason.clone(),
110 Errata::Critical { reason, formula: _ } => reason.clone(),
111 }
112 }
113
114 pub fn formula(&self) -> Arc<str> {
116 match self {
117 Errata::Three {
118 reason: _,
119 formula,
120 location: _,
121 } => formula.clone(),
122 Errata::Two { reason: _, formula } => formula.clone(),
123 Errata::One { reason: _ } => Value::empty_str(),
124 Errata::Critical { reason: _, formula } => formula.clone(),
125 }
126 }
127
128 pub fn location(&self) -> Arc<str> {
130 match self {
131 Errata::Three {
132 reason: _,
133 formula: _,
134 location,
135 } => location.clone(),
136 _ => Value::empty_str(),
137 }
138 }
139
140 pub fn print(&self, writer: &mut Writer) {
142 let (reason, formula, location) = match self {
143 Errata::Three {
144 reason,
145 formula,
146 location,
147 } => (reason.clone(), formula.clone(), location.clone()),
148 Errata::Two { reason, formula } => (reason.clone(), formula.clone(), Value::empty_str()),
149 Errata::One { reason } => (reason.clone(), Value::empty_str(), Value::empty_str()),
150 Errata::Critical { reason, formula } => (reason.clone(), formula.clone(), Value::empty_str()),
151 };
152 match writer.print_mode() {
153 PrintMode::QuoteEscape => {
155 if !formula.is_empty() {
156 writer.print(&formula);
157 } else {
158 writer.print(&reason);
159 }
160 }
161 _ => {
162 if !reason.is_empty() {
163 writer.print(&reason);
164 writer.write_eol();
165 }
166 writer.print(&formula);
167 writer.write_eol();
168 if !location.is_empty() && let Some(offset) = formula.find(&*location) {
169 for _ in 0..offset {
170 writer.write_char(' ');
171 }
172 writer.write_char('^');
173 writer.write_eol();
174 }
175 }
176 }
177 }
178
179 pub fn to_formula(&self) -> String {
181 let mut writer = Writer::formulizer();
182 self.print(&mut writer);
183 writer.finish()
184 }
185}
186
187impl WriterLike for Errata {
188 fn write(&self, writer: &mut Writer) {
189 self.print(writer);
190 }
191}
192
193impl fmt::Display for Errata {
194 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
195 write!(f, "{}", self.to_stringized())
196 }
197}