target_spec_miette/
imp.rs1use miette::{Diagnostic, LabeledSpan, SourceCode, SourceOffset, SourceSpan};
5use std::{error::Error as StdError, fmt};
6use target_spec::errors::{
7 CustomTripleCreateError, Error as TargetSpecError, ExpressionParseError, PlainStringParseError,
8 TripleParseError,
9};
10
11pub trait IntoMietteDiagnostic {
13 type IntoDiagnostic;
15
16 fn into_diagnostic(self) -> Self::IntoDiagnostic;
20}
21
22impl IntoMietteDiagnostic for TargetSpecError {
23 type IntoDiagnostic = Box<dyn Diagnostic + Send + Sync + 'static>;
24
25 fn into_diagnostic(self) -> Self::IntoDiagnostic {
26 match self {
27 Self::InvalidExpression(error) => Box::new(error.into_diagnostic()),
28 Self::InvalidTargetSpecString(error) => Box::new(error.into_diagnostic()),
29 Self::UnknownPlatformTriple(error) => Box::new(error.into_diagnostic()),
30 #[allow(deprecated)]
31 Self::CustomTripleCreate(error) => Box::new(error.into_diagnostic()),
32 Self::CustomPlatformCreate(error) => Box::new(error.into_diagnostic()),
33 other => Box::<dyn Diagnostic + Send + Sync + 'static>::from(other.to_string()),
34 }
35 }
36}
37
38#[derive(Clone, PartialEq, Eq)]
40pub struct ExpressionParseDiagnostic(ExpressionParseError);
41
42impl ExpressionParseDiagnostic {
43 pub fn new(error: ExpressionParseError) -> Self {
45 Self(error)
46 }
47}
48
49impl fmt::Debug for ExpressionParseDiagnostic {
50 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51 fmt::Debug::fmt(&self.0, f)
52 }
53}
54
55impl fmt::Display for ExpressionParseDiagnostic {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 fmt::Display::fmt(&self.0, f)
58 }
59}
60
61impl StdError for ExpressionParseDiagnostic {
62 fn source(&self) -> Option<&(dyn StdError + 'static)> {
63 self.0.source()
64 }
65}
66
67impl Diagnostic for ExpressionParseDiagnostic {
68 fn source_code(&self) -> Option<&dyn SourceCode> {
69 Some(&self.0.input)
70 }
71
72 fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
73 let label = LabeledSpan::new_with_span(Some(self.0.kind.to_string()), self.0.span.clone());
74 Some(Box::new(std::iter::once(label)))
75 }
76}
77
78impl IntoMietteDiagnostic for ExpressionParseError {
79 type IntoDiagnostic = ExpressionParseDiagnostic;
80
81 fn into_diagnostic(self) -> Self::IntoDiagnostic {
82 ExpressionParseDiagnostic::new(self)
83 }
84}
85
86#[derive(Clone, PartialEq, Eq)]
88pub struct TripleParseDiagnostic {
89 error: TripleParseError,
90 triple_str: String,
92}
93
94impl TripleParseDiagnostic {
95 pub fn new(error: TripleParseError) -> Self {
97 let triple_str = error.triple_str().to_owned();
98 Self { error, triple_str }
99 }
100}
101
102impl fmt::Debug for TripleParseDiagnostic {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 fmt::Debug::fmt(&self.error, f)
105 }
106}
107
108impl fmt::Display for TripleParseDiagnostic {
109 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110 fmt::Display::fmt(&self.error, f)
111 }
112}
113
114impl StdError for TripleParseDiagnostic {
115 fn source(&self) -> Option<&(dyn StdError + 'static)> {
116 self.error.source()
117 }
118}
119
120impl Diagnostic for TripleParseDiagnostic {
121 fn source_code(&self) -> Option<&dyn SourceCode> {
122 Some(&self.triple_str as &dyn SourceCode)
123 }
124
125 fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
126 let label = LabeledSpan::new_with_span(
127 Some(
128 self.error
129 .source()
130 .expect("TripleParseError always returns a source")
131 .to_string(),
132 ),
133 (0, self.triple_str.len()),
134 );
135 Some(Box::new(std::iter::once(label)))
136 }
137}
138
139impl IntoMietteDiagnostic for TripleParseError {
140 type IntoDiagnostic = TripleParseDiagnostic;
141
142 fn into_diagnostic(self) -> Self::IntoDiagnostic {
143 TripleParseDiagnostic::new(self)
144 }
145}
146
147#[derive(Clone, PartialEq, Eq)]
149pub struct PlainStringParseDiagnostic {
150 error: PlainStringParseError,
151 input: String,
153}
154
155impl PlainStringParseDiagnostic {
156 pub fn new(error: PlainStringParseError) -> Self {
158 let input = error.input.clone();
159 Self { error, input }
160 }
161}
162
163impl fmt::Debug for PlainStringParseDiagnostic {
164 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
165 fmt::Debug::fmt(&self.error, f)
166 }
167}
168
169impl fmt::Display for PlainStringParseDiagnostic {
170 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
171 f.write_str("invalid triple identifier")
174 }
175}
176
177impl StdError for PlainStringParseDiagnostic {
178 fn source(&self) -> Option<&(dyn StdError + 'static)> {
179 self.error.source()
180 }
181}
182
183impl Diagnostic for PlainStringParseDiagnostic {
184 fn source_code(&self) -> Option<&dyn SourceCode> {
185 Some(&self.input as &dyn SourceCode)
186 }
187
188 fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
189 let label = LabeledSpan::new_with_span(
190 Some("character must be alphanumeric, -, _ or .".to_owned()),
191 self.error.span(),
192 );
193 Some(Box::new(std::iter::once(label)))
194 }
195}
196
197impl IntoMietteDiagnostic for PlainStringParseError {
198 type IntoDiagnostic = PlainStringParseDiagnostic;
199
200 fn into_diagnostic(self) -> Self::IntoDiagnostic {
201 PlainStringParseDiagnostic::new(self)
202 }
203}
204
205impl IntoMietteDiagnostic for CustomTripleCreateError {
206 type IntoDiagnostic = CustomTripleCreateDiagnostic;
207
208 fn into_diagnostic(self) -> Self::IntoDiagnostic {
209 CustomTripleCreateDiagnostic::new(self)
210 }
211}
212
213pub struct CustomTripleCreateDiagnostic(CustomTripleCreateError);
215
216impl CustomTripleCreateDiagnostic {
217 pub fn new(error: CustomTripleCreateError) -> Self {
219 Self(error)
220 }
221}
222
223impl fmt::Debug for CustomTripleCreateDiagnostic {
224 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
225 fmt::Debug::fmt(&self.0, f)
226 }
227}
228
229impl fmt::Display for CustomTripleCreateDiagnostic {
230 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
231 fmt::Display::fmt(&self.0, f)
232 }
233}
234
235impl StdError for CustomTripleCreateDiagnostic {
236 fn source(&self) -> Option<&(dyn StdError + 'static)> {
237 if self.0.input().is_some() && self.0.line_and_column().is_some() {
239 None
240 } else {
241 self.0.source()
242 }
243 }
244}
245
246impl Diagnostic for CustomTripleCreateDiagnostic {
247 fn source_code(&self) -> Option<&dyn SourceCode> {
248 self.0.input_string().map(|input| input as &dyn SourceCode)
249 }
250
251 fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
252 let input = self.0.input()?;
255 let (line, column) = self.0.line_and_column()?;
256
257 let source_offset = SourceOffset::from_location(input, line, column);
258 let span = SourceSpan::new(source_offset, 0);
261
262 let label = LabeledSpan::new_with_span(self.0.label(), span);
263 Some(Box::new(std::iter::once(label)))
264 }
265}