Skip to content

Commit

Permalink
feat(protocol): improvements to snippets API
Browse files Browse the repository at this point in the history
  • Loading branch information
zkat committed Aug 8, 2021
1 parent 80e7dab commit 3584dc6
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 19 deletions.
18 changes: 11 additions & 7 deletions src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ that you can implement to get access to miette's (and related library's) full
reporting and such features.
*/

use std::fmt::Display;
use std::{fmt::Display, sync::Arc};

use crate::MietteError;

Expand Down Expand Up @@ -36,14 +36,16 @@ pub trait Diagnostic: std::error::Error {

/// Additional contextual snippets. This is typically used for adding
/// marked-up source file output the way compilers often do.
fn snippets(&self) -> Option<&[DiagnosticSnippet]> {
fn snippets(&self) -> Option<Box<dyn Iterator<Item = DiagnosticSnippet>>> {
None
}
}

impl std::error::Error for Box<dyn Diagnostic> {}

impl<T: Diagnostic + Send + Sync + 'static> From<T> for Box<dyn Diagnostic + Send + Sync + 'static> {
impl<T: Diagnostic + Send + Sync + 'static> From<T>
for Box<dyn Diagnostic + Send + Sync + 'static>
{
fn from(diag: T) -> Self {
Box::new(diag)
}
Expand Down Expand Up @@ -112,8 +114,10 @@ support Sources which are gigabytes or larger in size.
*/
pub trait Source: std::fmt::Debug + Send + Sync + 'static {
/// Read the bytes for a specific span from this Source.
fn read_span<'a>(&'a self, span: &SourceSpan)
-> Result<Box<dyn SpanContents + 'a>, MietteError>;
fn read_span<'a>(
&'a self,
span: &SourceSpan,
) -> Result<Box<dyn SpanContents + 'a>, MietteError>;
}

/**
Expand Down Expand Up @@ -166,14 +170,14 @@ impl<'a> SpanContents for MietteSpanContents<'a> {
/**
A snippet from a [Source] to be displayed with a message and possibly some highlights.
*/
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct DiagnosticSnippet {
/// Explanation of this specific diagnostic snippet.
pub message: Option<String>,
/// The "filename" for this snippet.
pub source_name: String,
/// A [Source] that can be used to read the actual text of a source.
pub source: Box<dyn Source>,
pub source: Arc<dyn Source>,
/// The primary [SourceSpan] where this diagnostic is located.
pub context: SourceSpan,
/// Additional [SourceSpan]s that mark specific sections of the span, for
Expand Down
12 changes: 8 additions & 4 deletions src/reporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::fmt;
use indenter::indented;

use crate::chain::Chain;
use crate::protocol::{Diagnostic, DiagnosticSnippet, DiagnosticReporter, Severity};
use crate::protocol::{Diagnostic, DiagnosticReporter, DiagnosticSnippet, Severity};

/**
Reference implementation of the [DiagnosticReporter] trait. This is generally
Expand All @@ -17,7 +17,11 @@ you want custom reporting for your tool or app.
pub struct MietteReporter;

impl MietteReporter {
fn render_snippet(&self, f: &mut fmt::Formatter<'_>, snippet: &DiagnosticSnippet) -> fmt::Result {
fn render_snippet(
&self,
f: &mut fmt::Formatter<'_>,
snippet: &DiagnosticSnippet,
) -> fmt::Result {
use fmt::Write as _;
write!(f, "\n[{}]", snippet.source_name)?;
if let Some(msg) = &snippet.message {
Expand Down Expand Up @@ -126,7 +130,7 @@ impl DiagnosticReporter for MietteReporter {
if let Some(snippets) = diagnostic.snippets() {
writeln!(f)?;
for snippet in snippets {
self.render_snippet(f, snippet)?;
self.render_snippet(f, &snippet)?;
}
}

Expand Down Expand Up @@ -166,7 +170,7 @@ impl DiagnosticReporter for JokeReporter {
"miette, her eyes enormous: you {} miette? you {}? oh! oh! jail for mother! jail for mother for One Thousand Years!!!!",
diagnostic.code(),
diagnostic.snippets().map(|snippets| {
snippets.iter().map(|snippet| snippet.message.clone()).collect::<Option<Vec<String>>>()
snippets.map(|snippet| snippet.message).collect::<Option<Vec<String>>>()
}).flatten().map(|x| x.join(", ")).unwrap_or_else(||"try and cause miette to panic".into())
)?;

Expand Down
18 changes: 10 additions & 8 deletions tests/reporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ impl Diagnostic for MyBad {
Some(&"try doing it better next time?")
}

fn snippets(&self) -> Option<&[DiagnosticSnippet]> {
Some(&self.snippets)
fn snippets(&self) -> Option<Box<dyn Iterator<Item = DiagnosticSnippet>>> {
Some(Box::new(self.snippets.clone().into_iter()))
}
}

Expand All @@ -48,20 +48,22 @@ fn basic() -> Result<(), MietteError> {
#[test]
fn fancy() -> Result<(), MietteError> {
let src = "source\n text\n here".to_string();
let len = src.len();
let err = MyBad {
snippets: vec![DiagnosticSnippet {
message: Some("This is the part that broke".into()),
source_name: "bad_file.rs".into(),
source: Box::new(src.clone()),
highlights: Some(vec![
("this bit here".into(), SourceSpan {
source: Arc::new(src),
highlights: Some(vec![(
"this bit here".into(),
SourceSpan {
start: 9.into(),
end: 12.into(),
})
]),
},
)]),
context: SourceSpan {
start: 0.into(),
end: (src.len() - 1).into(),
end: (len - 1).into(),
},
}],
};
Expand Down

0 comments on commit 3584dc6

Please sign in to comment.