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