Skip to content

Commit 0d5c2ce

Browse files
authoredFeb 4, 2024
feat(source-code): Don't override provided source code (#300)
BREAKING CHANGE: Source code is no longer overridden if it was provided by the diagnostic's own `source_code()` impl.
1 parent c0a298e commit 0d5c2ce

File tree

1 file changed

+87
-2
lines changed

1 file changed

+87
-2
lines changed
 

‎src/eyreish/wrapper.rs

+87-2
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ impl<E: Diagnostic, C: SourceCode> Diagnostic for WithSourceCode<E, C> {
163163
}
164164

165165
fn source_code(&self) -> Option<&dyn miette::SourceCode> {
166-
Some(&self.source_code)
166+
self.error.source_code().or(Some(&self.source_code))
167167
}
168168

169169
fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {
@@ -197,7 +197,7 @@ impl<C: SourceCode> Diagnostic for WithSourceCode<Report, C> {
197197
}
198198

199199
fn source_code(&self) -> Option<&dyn miette::SourceCode> {
200-
Some(&self.source_code)
200+
self.error.source_code().or(Some(&self.source_code))
201201
}
202202

203203
fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {
@@ -232,3 +232,88 @@ impl<C> StdError for WithSourceCode<Report, C> {
232232
self.error.source()
233233
}
234234
}
235+
236+
#[cfg(test)]
237+
mod tests {
238+
use thiserror::Error;
239+
240+
use crate::{Diagnostic, LabeledSpan, Report, SourceCode, SourceSpan};
241+
242+
#[derive(Error, Debug)]
243+
#[error("inner")]
244+
struct Inner {
245+
pub(crate) at: SourceSpan,
246+
pub(crate) source_code: Option<String>,
247+
}
248+
249+
impl Diagnostic for Inner {
250+
fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
251+
Some(Box::new(std::iter::once(LabeledSpan::underline(self.at))))
252+
}
253+
254+
fn source_code(&self) -> Option<&dyn SourceCode> {
255+
self.source_code.as_ref().map(|s| s as _)
256+
}
257+
}
258+
259+
#[derive(Error, Debug)]
260+
#[error("outer")]
261+
struct Outer {
262+
pub(crate) errors: Vec<Inner>,
263+
}
264+
265+
impl Diagnostic for Outer {
266+
fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {
267+
Some(Box::new(self.errors.iter().map(|e| e as _)))
268+
}
269+
}
270+
271+
#[test]
272+
fn no_override() {
273+
let inner_source = "hello world";
274+
let outer_source = "abc";
275+
276+
let report = Report::from(Inner {
277+
at: (0..5).into(),
278+
source_code: Some(inner_source.to_string()),
279+
})
280+
.with_source_code(outer_source.to_string());
281+
282+
let underlined = String::from_utf8(
283+
report
284+
.source_code()
285+
.unwrap()
286+
.read_span(&(0..5).into(), 0, 0)
287+
.unwrap()
288+
.data()
289+
.to_vec(),
290+
)
291+
.unwrap();
292+
assert_eq!(underlined, "hello");
293+
}
294+
295+
#[test]
296+
#[cfg(feature = "fancy")]
297+
fn two_source_codes() {
298+
let inner_source = "hello world";
299+
let outer_source = "abc";
300+
301+
let report = Report::from(Outer {
302+
errors: vec![
303+
Inner {
304+
at: (0..5).into(),
305+
source_code: Some(inner_source.to_string()),
306+
},
307+
Inner {
308+
at: (1..2).into(),
309+
source_code: None,
310+
},
311+
],
312+
})
313+
.with_source_code(outer_source.to_string());
314+
315+
let message = format!("{:?}", report);
316+
assert!(message.contains(inner_source));
317+
assert!(message.contains(outer_source));
318+
}
319+
}

0 commit comments

Comments
 (0)
Please sign in to comment.