Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow implementations of SpanContents to own their backing data #411

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/handlers/graphical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1183,7 +1183,7 @@ impl GraphicalReportHandler {
&'a self,
source: &'a dyn SourceCode,
context_span: &'a SourceSpan,
) -> Result<(Box<dyn SpanContents<'a> + 'a>, Vec<Line>), fmt::Error> {
) -> Result<(Box<dyn SpanContents + 'a>, Vec<Line>), fmt::Error> {
let context_data = source
.read_span(context_span, self.context_lines, self.context_lines)
.map_err(|_| fmt::Error)?;
Expand Down
4 changes: 2 additions & 2 deletions src/handlers/narratable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ impl NarratableReportHandler {
.map(|label| {
source.read_span(label.inner(), self.context_lines, self.context_lines)
})
.collect::<Result<Vec<Box<dyn SpanContents<'_>>>, MietteError>>()
.collect::<Result<Vec<Box<dyn SpanContents>>, MietteError>>()
.map_err(|_| fmt::Error)?;
let mut contexts = Vec::new();
for (right, right_conts) in labels.iter().cloned().zip(contents.iter()) {
Expand Down Expand Up @@ -286,7 +286,7 @@ impl NarratableReportHandler {
&'a self,
source: &'a dyn SourceCode,
context_span: &'a SourceSpan,
) -> Result<(Box<dyn SpanContents<'a> + 'a>, Vec<Line>), fmt::Error> {
) -> Result<(Box<dyn SpanContents + 'a>, Vec<Line>), fmt::Error> {
let context_data = source
.read_span(context_span, self.context_lines, self.context_lines)
.map_err(|_| fmt::Error)?;
Expand Down
2 changes: 1 addition & 1 deletion src/highlighters/blank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub struct BlankHighlighter;
impl Highlighter for BlankHighlighter {
fn start_highlighter_state<'h>(
&'h self,
_source: &dyn SpanContents<'_>,
_source: &(dyn SpanContents + 'h),
) -> Box<dyn super::HighlighterState + 'h> {
Box::new(BlankHighlighterState)
}
Expand Down
2 changes: 1 addition & 1 deletion src/highlighters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub trait Highlighter {
/// responsible for the actual rendering.
fn start_highlighter_state<'h>(
&'h self,
source: &dyn SpanContents<'_>,
source: &(dyn SpanContents + 'h),
) -> Box<dyn HighlighterState + 'h>;
}

Expand Down
4 changes: 2 additions & 2 deletions src/highlighters/syntect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl Default for SyntectHighlighter {
impl Highlighter for SyntectHighlighter {
fn start_highlighter_state<'h>(
&'h self,
source: &dyn SpanContents<'_>,
source: &(dyn SpanContents + 'h),
) -> Box<dyn HighlighterState + 'h> {
if let Some(syntax) = self.detect_syntax(source) {
let highlighter = syntect::Highlighter::new(&self.theme);
Expand Down Expand Up @@ -82,7 +82,7 @@ impl SyntectHighlighter {
}

/// Determine syntect [`SyntaxReference`] to use for given [`SpanContents`].
fn detect_syntax(&self, contents: &dyn SpanContents<'_>) -> Option<&syntect::SyntaxReference> {
fn detect_syntax(&self, contents: &dyn SpanContents) -> Option<&syntect::SyntaxReference> {
// use language if given
if let Some(language) = contents.language() {
return self.syntax_set.find_syntax_by_name(language);
Expand Down
58 changes: 44 additions & 14 deletions src/named_source.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{MietteError, MietteSpanContents, SourceCode, SpanContents};
use crate::{MietteError, SourceCode, SpanContents};

/// Utility struct for when you have a regular [`SourceCode`] type that doesn't
/// implement `name`. For example [`String`]. Or if you want to override the
Expand Down Expand Up @@ -51,28 +51,58 @@ impl<S: SourceCode + 'static> NamedSource<S> {
self
}
}
/// Utility struct used by [`NamedSource`] to attach a file name to an inner [`SpanContents`] value
#[derive(Debug)]
pub struct NamedSpanContents<T: ?Sized> {
inner: Box<T>,
name: Box<str>,
language: Option<Box<str>>,
}
impl<T: SpanContents + ?Sized> SpanContents for NamedSpanContents<T> {
#[inline]
fn data(&self) -> &[u8] {
self.inner.data()
}
#[inline]
fn span(&self) -> &crate::SourceSpan {
self.inner.span()
}
#[inline]
fn line(&self) -> usize {
self.inner.line()
}
#[inline]
fn column(&self) -> usize {
self.inner.column()
}
#[inline]
fn line_count(&self) -> usize {
self.inner.line_count()
}
#[inline]
fn name(&self) -> Option<&str> {
Some(&self.name)
}
#[inline]
fn language(&self) -> Option<&str> {
self.language.as_deref()
}
}

impl<S: SourceCode + 'static> SourceCode for NamedSource<S> {
fn read_span<'a>(
&'a self,
span: &crate::SourceSpan,
context_lines_before: usize,
context_lines_after: usize,
) -> Result<Box<dyn SpanContents<'a> + 'a>, MietteError> {
) -> Result<Box<dyn SpanContents + 'a>, MietteError> {
let inner_contents =
self.inner()
.read_span(span, context_lines_before, context_lines_after)?;
let mut contents = MietteSpanContents::new_named(
self.name.clone(),
inner_contents.data(),
*inner_contents.span(),
inner_contents.line(),
inner_contents.column(),
inner_contents.line_count(),
);
if let Some(language) = &self.language {
contents = contents.with_language(language);
}
Ok(Box::new(contents))
Ok(Box::new(NamedSpanContents {
inner: inner_contents,
name: self.name.clone().into_boxed_str(),
language: self.language.as_ref().map(|v| v.clone().into_boxed_str()),
}))
}
}
10 changes: 5 additions & 5 deletions src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ pub trait SourceCode: Send + Sync {
span: &SourceSpan,
context_lines_before: usize,
context_lines_after: usize,
) -> Result<Box<dyn SpanContents<'a> + 'a>, MietteError>;
) -> Result<Box<dyn SpanContents + 'a>, MietteError>;
}

/// A labeled [`SourceSpan`].
Expand Down Expand Up @@ -434,9 +434,9 @@ Contents of a [`SourceCode`] covered by [`SourceSpan`].

Includes line and column information to optimize highlight calculations.
*/
pub trait SpanContents<'a> {
pub trait SpanContents {
/// Reference to the data inside the associated span, in bytes.
fn data(&self) -> &'a [u8];
fn data(&self) -> &[u8];
/// [`SourceSpan`] representing the span covered by this `SpanContents`.
fn span(&self) -> &SourceSpan;
/// An optional (file?) name for the container of this `SpanContents`.
Expand Down Expand Up @@ -530,8 +530,8 @@ impl<'a> MietteSpanContents<'a> {
}
}

impl<'a> SpanContents<'a> for MietteSpanContents<'a> {
fn data(&self) -> &'a [u8] {
impl<'a> SpanContents for MietteSpanContents<'a> {
fn data(&self) -> &[u8] {
self.data
}
fn span(&self) -> &SourceSpan {
Expand Down
16 changes: 8 additions & 8 deletions src/source_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl SourceCode for [u8] {
span: &SourceSpan,
context_lines_before: usize,
context_lines_after: usize,
) -> Result<Box<dyn SpanContents<'a> + 'a>, MietteError> {
) -> Result<Box<dyn SpanContents + 'a>, MietteError> {
let contents = context_info(self, span, context_lines_before, context_lines_after)?;
Ok(Box::new(contents))
}
Expand All @@ -110,7 +110,7 @@ impl<'src> SourceCode for &'src [u8] {
span: &SourceSpan,
context_lines_before: usize,
context_lines_after: usize,
) -> Result<Box<dyn SpanContents<'a> + 'a>, MietteError> {
) -> Result<Box<dyn SpanContents + 'a>, MietteError> {
<[u8] as SourceCode>::read_span(self, span, context_lines_before, context_lines_after)
}
}
Expand All @@ -121,7 +121,7 @@ impl SourceCode for Vec<u8> {
span: &SourceSpan,
context_lines_before: usize,
context_lines_after: usize,
) -> Result<Box<dyn SpanContents<'a> + 'a>, MietteError> {
) -> Result<Box<dyn SpanContents + 'a>, MietteError> {
<[u8] as SourceCode>::read_span(self, span, context_lines_before, context_lines_after)
}
}
Expand All @@ -132,7 +132,7 @@ impl SourceCode for str {
span: &SourceSpan,
context_lines_before: usize,
context_lines_after: usize,
) -> Result<Box<dyn SpanContents<'a> + 'a>, MietteError> {
) -> Result<Box<dyn SpanContents + 'a>, MietteError> {
<[u8] as SourceCode>::read_span(
self.as_bytes(),
span,
Expand All @@ -149,7 +149,7 @@ impl<'s> SourceCode for &'s str {
span: &SourceSpan,
context_lines_before: usize,
context_lines_after: usize,
) -> Result<Box<dyn SpanContents<'a> + 'a>, MietteError> {
) -> Result<Box<dyn SpanContents + 'a>, MietteError> {
<str as SourceCode>::read_span(self, span, context_lines_before, context_lines_after)
}
}
Expand All @@ -160,7 +160,7 @@ impl SourceCode for String {
span: &SourceSpan,
context_lines_before: usize,
context_lines_after: usize,
) -> Result<Box<dyn SpanContents<'a> + 'a>, MietteError> {
) -> Result<Box<dyn SpanContents + 'a>, MietteError> {
<str as SourceCode>::read_span(self, span, context_lines_before, context_lines_after)
}
}
Expand All @@ -171,7 +171,7 @@ impl<T: ?Sized + SourceCode> SourceCode for Arc<T> {
span: &SourceSpan,
context_lines_before: usize,
context_lines_after: usize,
) -> Result<Box<dyn SpanContents<'a> + 'a>, MietteError> {
) -> Result<Box<dyn SpanContents + 'a>, MietteError> {
self.as_ref()
.read_span(span, context_lines_before, context_lines_after)
}
Expand All @@ -191,7 +191,7 @@ where
span: &SourceSpan,
context_lines_before: usize,
context_lines_after: usize,
) -> Result<Box<dyn SpanContents<'a> + 'a>, MietteError> {
) -> Result<Box<dyn SpanContents + 'a>, MietteError> {
self.as_ref()
.read_span(span, context_lines_before, context_lines_after)
}
Expand Down