1 use crate::{MietteError, MietteSpanContents, SourceCode, SpanContents};
2 
3 /// Utility struct for when you have a regular [`SourceCode`] type that doesn't
4 /// implement `name`. For example [`String`]. Or if you want to override the
5 /// `name` returned by the `SourceCode`.
6 pub struct NamedSource {
7     source: Box<dyn SourceCode + 'static>,
8     name: String,
9 }
10 
11 impl std::fmt::Debug for NamedSource {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result12     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13         f.debug_struct("NamedSource")
14             .field("name", &self.name)
15             .field("source", &"<redacted>");
16         Ok(())
17     }
18 }
19 
20 impl NamedSource {
21     /// Create a new `NamedSource` using a regular [`SourceCode`] and giving
22     /// its returned [`SpanContents`] a name.
new(name: impl AsRef<str>, source: impl SourceCode + Send + Sync + 'static) -> Self23     pub fn new(name: impl AsRef<str>, source: impl SourceCode + Send + Sync + 'static) -> Self {
24         Self {
25             source: Box::new(source),
26             name: name.as_ref().to_string(),
27         }
28     }
29 
30     /// Gets the name of this `NamedSource`.
name(&self) -> &str31     pub fn name(&self) -> &str {
32         &self.name
33     }
34 
35     /// Returns a reference the inner [`SourceCode`] type for this
36     /// `NamedSource`.
inner(&self) -> &(dyn SourceCode + 'static)37     pub fn inner(&self) -> &(dyn SourceCode + 'static) {
38         &*self.source
39     }
40 }
41 
42 impl SourceCode for NamedSource {
read_span<'a>( &'a self, span: &crate::SourceSpan, context_lines_before: usize, context_lines_after: usize, ) -> Result<Box<dyn SpanContents<'a> + 'a>, MietteError>43     fn read_span<'a>(
44         &'a self,
45         span: &crate::SourceSpan,
46         context_lines_before: usize,
47         context_lines_after: usize,
48     ) -> Result<Box<dyn SpanContents<'a> + 'a>, MietteError> {
49         let contents = self
50             .inner()
51             .read_span(span, context_lines_before, context_lines_after)?;
52         Ok(Box::new(MietteSpanContents::new_named(
53             self.name.clone(),
54             contents.data(),
55             *contents.span(),
56             contents.line(),
57             contents.column(),
58             contents.line_count(),
59         )))
60     }
61 }
62