From 2d4bb53e743e0ac64d1d603866f9448decac2a1e Mon Sep 17 00:00:00 2001 From: Aatif Syed Date: Mon, 8 Dec 2025 12:53:56 +0000 Subject: [PATCH] feat: Renderer::render_to(impl Write, ..) --- src/renderer/mod.rs | 11 ++++++++++- src/renderer/render.rs | 28 ++++++++++++++++------------ src/renderer/styled_buffer.rs | 14 +++++++------- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index eaab6329..b5b7f740 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -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; @@ -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(&self, to: W, groups: Report<'_>) -> fmt::Result { + render::render_to(to, self, groups) } } diff --git a/src/renderer/render.rs b/src/renderer/render.rs index 283fe770..71bf8d9b 100644 --- a/src/renderer/render.rs +++ b/src/renderer/render.rs @@ -24,9 +24,13 @@ 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 { @@ -34,7 +38,6 @@ pub(crate) fn render(renderer: &Renderer, groups: Report<'_>) -> String { } else { num_decimal_digits(max_line_num) }; - let mut out_string = String::new(); let group_len = groups.len(); for ( g, @@ -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 { +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"); @@ -306,10 +311,9 @@ fn render_short_message(renderer: &Renderer, groups: &[Group<'_>]) -> Result, stylesheet: &Stylesheet, - str: &mut String, ) -> Result<(), fmt::Error> { for (i, line) in self.lines.iter().enumerate() { let mut current_style = stylesheet.none; @@ -51,16 +51,16 @@ impl StyledBuffer { 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(())