Skip to content
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
11 changes: 10 additions & 1 deletion src/renderer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ pub(crate) mod stylesheet;
mod margin;
mod styled_buffer;

use std::fmt;

use crate::Report;

pub(crate) use render::normalize_whitespace;
Expand Down Expand Up @@ -193,7 +195,14 @@ impl Renderer {
impl Renderer {
/// Render a diagnostic [`Report`]
pub fn render(&self, groups: Report<'_>) -> String {
render::render(self, groups)
let mut s = String::new();
self.render_to(&mut s, groups)
.expect("String::write_fmt is infallible");
s
}
/// Render a diagnostic [`Report`] to the given [`Write`](fmt::Write)r
pub fn render_to<W: fmt::Write>(&self, to: W, groups: Report<'_>) -> fmt::Result {
render::render_to(to, self, groups)
}
}

Expand Down
28 changes: 16 additions & 12 deletions src/renderer/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,20 @@ use crate::{

const ANONYMIZED_LINE_NUM: &str = "LL";

pub(crate) fn render(renderer: &Renderer, groups: Report<'_>) -> String {
pub(crate) fn render_to(
mut to: impl fmt::Write,
renderer: &Renderer,
groups: Report<'_>,
) -> fmt::Result {
if renderer.short_message {
render_short_message(renderer, groups).unwrap()
render_short_message(to, renderer, groups)
} else {
let (max_line_num, og_primary_path, groups) = pre_process(groups);
let max_line_num_len = if renderer.anonymized_line_numbers {
ANONYMIZED_LINE_NUM.len()
} else {
num_decimal_digits(max_line_num)
};
let mut out_string = String::new();
let group_len = groups.len();
for (
g,
Expand Down Expand Up @@ -220,19 +223,21 @@ pub(crate) fn render(renderer: &Renderer, groups: Report<'_>) -> String {
}
}
buffer
.render(&level, &renderer.stylesheet, &mut out_string)
.render_to(&mut to, &level, &renderer.stylesheet)
.unwrap();
if g != group_len - 1 {
use std::fmt::Write;

writeln!(out_string).unwrap();
writeln!(to).unwrap();
}
}
out_string
Ok(())
}
}

fn render_short_message(renderer: &Renderer, groups: &[Group<'_>]) -> Result<String, fmt::Error> {
fn render_short_message(
to: impl fmt::Write,
renderer: &Renderer,
groups: &[Group<'_>],
) -> fmt::Result {
let mut buffer = StyledBuffer::new();
let mut labels = None;
let group = groups.first().expect("Expected at least one group");
Expand Down Expand Up @@ -306,10 +311,9 @@ fn render_short_message(renderer: &Renderer, groups: &[Group<'_>]) -> Result<Str
buffer.append(0, &format!(": {labels}"), ElementStyle::NoStyle);
}

let mut out_string = String::new();
buffer.render(&title.level, &renderer.stylesheet, &mut out_string)?;
buffer.render_to(to, &title.level, &renderer.stylesheet)?;

Ok(out_string)
Ok(())
}

#[allow(clippy::too_many_arguments)]
Expand Down
14 changes: 7 additions & 7 deletions src/renderer/styled_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,28 +39,28 @@ impl StyledBuffer {
}
}

pub(crate) fn render(
pub(crate) fn render_to(
&self,
mut to: impl Write,
level: &Level<'_>,
stylesheet: &Stylesheet,
str: &mut String,
) -> Result<(), fmt::Error> {
for (i, line) in self.lines.iter().enumerate() {
let mut current_style = stylesheet.none;
for StyledChar { ch, style } in line {
let ch_style = style.color_spec(level, stylesheet);
if ch_style != current_style {
if !line.is_empty() {
write!(str, "{current_style:#}")?;
write!(to, "{current_style:#}")?;
}
current_style = ch_style;
write!(str, "{current_style}")?;
write!(to, "{current_style}")?;
}
write!(str, "{ch}")?;
write!(to, "{ch}")?;
}
write!(str, "{current_style:#}")?;
write!(to, "{current_style:#}")?;
if i != self.lines.len() - 1 {
writeln!(str)?;
writeln!(to)?;
}
}
Ok(())
Expand Down