Skip to content

Commit

Permalink
fix(zero length, no context): Add Option to distinguish between "curr…
Browse files Browse the repository at this point in the history
…ent line" and "just the span"

Fixes #355

Change the number of context lines from usize to Option<usize> to allow
choosing between "just the span" (as implemented previously when using
0 context line) using `None`, and displaying the error line without
extra context (not possible before) using `Some(0)`.
  • Loading branch information
Nahor committed Mar 20, 2024
1 parent f7fa50d commit d63b2bb
Show file tree
Hide file tree
Showing 9 changed files with 343 additions and 57 deletions.
2 changes: 1 addition & 1 deletion src/eyreish/wrapper.rs
Expand Up @@ -283,7 +283,7 @@ mod tests {
report
.source_code()
.unwrap()
.read_span(&(0..5).into(), 0, 0)
.read_span(&(0..5).into(), None, None)
.unwrap()
.data()
.to_vec(),
Expand Down
27 changes: 21 additions & 6 deletions src/handlers/graphical.rs
Expand Up @@ -28,7 +28,7 @@ pub struct GraphicalReportHandler {
pub(crate) termwidth: usize,
pub(crate) theme: GraphicalTheme,
pub(crate) footer: Option<String>,
pub(crate) context_lines: usize,
pub(crate) context_lines: Option<usize>,
pub(crate) tab_width: usize,
pub(crate) with_cause_chain: bool,
pub(crate) wrap_lines: bool,
Expand All @@ -55,7 +55,7 @@ impl GraphicalReportHandler {
termwidth: 200,
theme: GraphicalTheme::default(),
footer: None,
context_lines: 1,
context_lines: Some(1),
tab_width: 4,
with_cause_chain: true,
wrap_lines: true,
Expand All @@ -74,7 +74,7 @@ impl GraphicalReportHandler {
termwidth: 200,
theme,
footer: None,
context_lines: 1,
context_lines: Some(1),
tab_width: 4,
wrap_lines: true,
with_cause_chain: true,
Expand Down Expand Up @@ -159,7 +159,7 @@ impl GraphicalReportHandler {
self
}

/// Sets the word splitter to usewhen wrapping.
/// Sets the word splitter to use when wrapping.
pub fn with_word_splitter(mut self, word_splitter: textwrap::WordSplitter) -> Self {
self.word_splitter = Some(word_splitter);
self
Expand All @@ -172,7 +172,22 @@ impl GraphicalReportHandler {
}

/// Sets the number of lines of context to show around each error.
pub fn with_context_lines(mut self, lines: usize) -> Self {
///
/// If `0`, then only the span content will be shown (equivalent to
/// `with_opt_context_lines(None)`).\
/// Use `with_opt_context_lines(Some(0))` if you want the whole line
/// containing the error without extra context.
pub fn with_context_lines(self, lines: usize) -> Self {
self.with_opt_context_lines((lines != 0).then_some(lines))
}

/// Sets the number of lines of context to show around each error.
///
/// `None` means only the span content (and possibly the content in between
/// multiple adjacent labels) will be shown.\
/// `Some(0)` will show the whole line containing the label.\
/// `Some(n)` will show the whole line plus n line before and after the label.
pub fn with_opt_context_lines(mut self, lines: Option<usize>) -> Self {
self.context_lines = lines;
self
}
Expand Down Expand Up @@ -559,7 +574,7 @@ impl GraphicalReportHandler {
// as the reference point for line/column information.
let primary_contents = match primary_label {
Some(label) => source
.read_span(label.inner(), 0, 0)
.read_span(label.inner(), None, None)
.map_err(|_| fmt::Error)?,
None => contents,
};
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/json.rs
Expand Up @@ -159,7 +159,7 @@ impl JSONReportHandler {
) -> fmt::Result {
if let Some(mut labels) = diagnostic.labels() {
if let Some(label) = labels.next() {
if let Ok(span_content) = source.read_span(label.inner(), 0, 0) {
if let Ok(span_content) = source.read_span(label.inner(), None, None) {
let filename = span_content.name().unwrap_or_default();
return write!(f, r#""filename": "{}","#, escape(filename));
}
Expand Down
21 changes: 18 additions & 3 deletions src/handlers/narratable.rs
Expand Up @@ -13,7 +13,7 @@ non-graphical environments, such as non-TTY output.
*/
#[derive(Debug, Clone)]
pub struct NarratableReportHandler {
context_lines: usize,
context_lines: Option<usize>,
with_cause_chain: bool,
footer: Option<String>,
}
Expand All @@ -24,7 +24,7 @@ impl NarratableReportHandler {
pub const fn new() -> Self {
Self {
footer: None,
context_lines: 1,
context_lines: Some(1),
with_cause_chain: true,
}
}
Expand All @@ -49,7 +49,22 @@ impl NarratableReportHandler {
}

/// Sets the number of lines of context to show around each error.
pub const fn with_context_lines(mut self, lines: usize) -> Self {
///
/// If `0`, then only the span content will be shown (equivalent to
/// `with_opt_context_lines(None)`).\
/// Use `with_opt_context_lines(Some(0))` if you want the whole line
/// containing the error without extra context.
pub fn with_context_lines(self, lines: usize) -> Self {
self.with_opt_context_lines((lines != 0).then_some(lines))
}

/// Sets the number of lines of context to show around each error.
///
/// `None` means only the span content (and possibly the content in between
/// multiple adjacent labels) will be shown.\
/// `Some(0)` will show the whole line containing the label.\
/// `Some(n)` will show the whole line plus n line before and after the label.
pub fn with_opt_context_lines(mut self, lines: Option<usize>) -> Self {
self.context_lines = lines;
self
}
Expand Down
4 changes: 2 additions & 2 deletions src/named_source.rs
Expand Up @@ -56,8 +56,8 @@ 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,
context_lines_before: Option<usize>,
context_lines_after: Option<usize>,
) -> Result<Box<dyn SpanContents<'a> + 'a>, MietteError> {
let inner_contents =
self.inner()
Expand Down
9 changes: 7 additions & 2 deletions src/protocol.rs
Expand Up @@ -247,11 +247,16 @@ gigabytes or larger in size.
pub trait SourceCode: Send + Sync {
/// Read the bytes for a specific span from this `SourceCode`, keeping a
/// certain number of lines before and after the span as context.
/// When the `context_lines_before` (resp. `context_lines_after`) is set to
/// `None`, the span content must start (resp. stop) at the **span** boundary.
/// When set to `Some(0)`, the content should start (resp. stop) at the
/// **line** boundary. When set to `Some(n)`, the content should include the
/// _n_ lines before (resp. after) the span.
fn read_span<'a>(
&'a self,
span: &SourceSpan,
context_lines_before: usize,
context_lines_after: usize,
context_lines_before: Option<usize>,
context_lines_after: Option<usize>,
) -> Result<Box<dyn SpanContents<'a> + 'a>, MietteError>;
}

Expand Down

0 comments on commit d63b2bb

Please sign in to comment.