pub struct Report<'a> { /* private fields */ }Expand description
A diagnostic report builder.
The lifetime 'a indicates that all string references passed to the report
must live at least as long as the report itself. This enables zero-copy
string passing to the underlying C library.
§Source Management
Sources are managed through a Cache and assigned IDs based on registration
order: first source is 0, second is 1, etc. The cache is then passed to rendering
methods.
§Example
use musubi::{Report, Cache, Level};
let cache = Cache::new()
.with_source(("let x = 42;", "main.rs")) // src_id = 0
.with_source(("fn foo() {}", "lib.rs")); // src_id = 1
let mut report = Report::new()
.with_title(Level::Error, "Error")
.with_label((0..3, 0)) // label in source 0
.with_message("here")
.with_label((3..6, 1)) // label in source 1
.with_message("and here");
report.render_to_stdout(&cache)?;§Lifetime Safety
Source strings must outlive the report. This will not compile:
use musubi::{Report, Level};
fn bad() -> String {
let mut report = Report::new();
{
let code = String::from("let x = 42;");
report.with_source((code.as_str(), "test.rs"));
} // code dropped here, but report still holds reference
report.render_to_string(0, 0)
}Implementations§
Source§impl<'a> Report<'a>
impl<'a> Report<'a>
Sourcepub fn with_config(self, config: Config<'a>) -> Self
pub fn with_config(self, config: Config<'a>) -> Self
Configure the report.
Sourcepub fn reset(self) -> Self
pub fn reset(self) -> Self
Reset the report for reuse.
Clears all labels, messages, and configuration, allowing the same Report instance to be used for rendering a different diagnostic.
§Example
let mut report = Report::new()
.with_title(Level::Error, "First error");
// ... render ...
report.render_to_string("")?;
let mut report = report.reset()
.with_title(Level::Warning, "Second warning");
// ... render again ...
report.render_to_string("")?;Sourcepub fn with_title<L: Into<TitleLevel<'a>>>(
self,
level: L,
message: &'a str,
) -> Self
pub fn with_title<L: Into<TitleLevel<'a>>>( self, level: L, message: &'a str, ) -> Self
Set the title and level.
Accepts either a standard level or a custom level name:
with_title(Level::Error, "message")- standard levelwith_title("Note", "message")- custom level name
§Example
Report::new()
.with_title(Level::Error, "Something went wrong")
// Or with custom level:
.with_title("Note", "Something to note")
// ...Sourcepub fn with_code(self, code: &'a str) -> Self
pub fn with_code(self, code: &'a str) -> Self
Set the error code for this diagnostic.
The error code is typically displayed in brackets before the title,
like [E0001] or [W123].
§Example
Report::new()
.with_title(Level::Error, "Type mismatch")
.with_code("E0308") // Displayed as [E0308]
// ...Sourcepub fn with_location(self, pos: usize, src_id: impl Into<mu_Id>) -> Self
pub fn with_location(self, pos: usize, src_id: impl Into<mu_Id>) -> Self
Set the primary location for this diagnostic.
This location is displayed in the diagnostic header, showing where the error occurred.
§Parameters
pos: Byte or character position in the source (depending onIndexType)src_id: Source ID (0 for first source, 1 for second, etc.)
§Example
Report::new()
.with_title(Level::Error, "Syntax error")
.with_location(42, 0) // Position 42 in source 0
// ...Sourcepub fn with_label<L: Into<LabelSpan>>(self, span: L) -> Self
pub fn with_label<L: Into<LabelSpan>>(self, span: L) -> Self
Add a label at the given byte range.
The src_id is the source registration order (0 for first source, 1 for second, etc.).
§Example
Report::new()
.with_title(Level::Error, "Error")
.with_label((0..3, 0)) // label in source 0
.with_message("here")
// ...Sourcepub fn with_message(self, msg: &'a str) -> Self
pub fn with_message(self, msg: &'a str) -> Self
Set the message for the last added label.
The message is displayed next to the label’s marker/arrow, providing explanation or context for the highlighted code.
§Example
Report::new()
.with_label(0..3)
.with_message("expected identifier here") // ← message for this label
.with_label(10..15)
.with_message("found number instead") // ← message for next label
// ...Sourcepub fn with_color<C: IntoColor>(self, color: C) -> Self
pub fn with_color<C: IntoColor>(self, color: C) -> Self
Set the color for the last added label.
This method accepts anything that implements IntoColor, including:
&dyn Color- Custom color trait objects&GenColor- Pre-generated colors fromColorGenerator
§Examples
Using a custom color:
struct MyColor;
impl Color for MyColor {
fn color(&self, w: &mut dyn Write, kind: ColorKind) -> std::io::Result<()> {
write!(w, "\x1b[31m") // Red
}
}
let color = MyColor;
Report::new()
// ...
.with_label(0..4)
.with_color(&color)
// ...Using a color generator:
let mut cg = ColorGenerator::new();
let report = Report::new()
// ...
.with_label(0..4)
.with_color(&cg.next_color())
// ...;Sourcepub fn with_order(self, order: i32) -> Self
pub fn with_order(self, order: i32) -> Self
Set the display order for the last added label.
Labels with lower order values are displayed first (closer to the code). Labels with the same order are displayed in the order they were added.
Default: 0
§Example
Report::new()
// ...
.with_label(0..4)
.with_message("second")
.with_order(1) // Display this label later
.with_title(Level::Error, "Error")
.with_label(0..4)
.with_message("first")
.with_order(-1) // Display this label first
// ...Sourcepub fn with_priority(self, priority: i32) -> Self
pub fn with_priority(self, priority: i32) -> Self
Set the priority for the last added label.
Priority controls how overlapping labels are rendered when multiple labels cover the same source location. Labels with higher priority will be drawn on top, potentially obscuring lower-priority labels.
Higher values = higher priority = drawn on top.
Default: 0
§Example
Report::new()
// ...
.with_label(0..10)
.with_message("low priority")
.with_priority(0) // May be obscured by overlapping labels
.with_label(5..15)
.with_message("high priority")
.with_priority(10) // Will be drawn on top
// ...Sourcepub fn with_help(self, msg: &'a str) -> Self
pub fn with_help(self, msg: &'a str) -> Self
Add a help message to the diagnostic.
Help messages appear at the end of the diagnostic, providing suggestions or additional context.
Multiple help messages can be added and will be displayed in order.
§Example
Report::new()
.with_title(Level::Error, "Type error")
.with_label(0..4)
.with_message("expected String")
.with_help("try converting with .to_string()")
// ...Sourcepub fn with_note(self, msg: &'a str) -> Self
pub fn with_note(self, msg: &'a str) -> Self
Add a note message to the diagnostic.
Notes appear at the end of the diagnostic, providing additional information or context.
Multiple notes can be added and will be displayed in order.
§Example
Report::new()
// ...
.with_title(Level::Warning, "Unused variable")
.with_label(0..4)
.with_message("never used")
.with_note("consider prefixing with an underscore: `_code`")
// ...Sourcepub fn render_to_string(&mut self, cache: impl Into<RawCache>) -> Result<String>
pub fn render_to_string(&mut self, cache: impl Into<RawCache>) -> Result<String>
Render the report to a String.
This is a convenience method that captures the rendered output into a String instead of writing to stdout or a file.
§Parameters
cache: Source cache containing the code to display. Can be:&Cache- A persistent cache with multiple sources&str- A single source string (borrowed)(&str, &str)- Source content and filename(&str, &str, i32)- Source content, filename, and line offset for adjusting displayed line numbers- Custom types implementing
Sourcetrait
§Example
let output = Report::new()
.with_title(Level::Error, "Syntax error")
.with_label(0..3)
.with_message("unexpected token")
.render_to_string(("let x", "main.rs"))?;
println!("{}", output);Sourcepub fn render_to_stdout(&mut self, cache: impl Into<RawCache>) -> Result<()>
pub fn render_to_stdout(&mut self, cache: impl Into<RawCache>) -> Result<()>
Render the report directly to stdout.
This is the most efficient way to display diagnostics, writing directly to the terminal without intermediate buffering.
§Parameters
cache: Source cache or source content. Can be&Cache,&str,(&str, &str),(&str, &str, i32), or customSourceimplementations. The third element (if present) is a line offset for adjusting displayed line numbers.
§Example
Report::new()
.with_title(Level::Error, "Error message")
.with_label(0..5)
.render_to_stdout(("let x = 42;", "main.rs"))?;Sourcepub fn render_to_writer<'b, W: Write>(
&'b mut self,
writer: &'b mut W,
cache: impl Into<RawCache>,
) -> Result<()>
pub fn render_to_writer<'b, W: Write>( &'b mut self, writer: &'b mut W, cache: impl Into<RawCache>, ) -> Result<()>
Render the report to any type implementing Write.
This allows rendering to files, buffers, or any custom writer.
§Parameters
writer: Mutable reference to any type implementingstd::io::Writecache: Source cache or source content. Can be&Cache,&str,(&str, &str),(&str, &str, i32), or customSourceimplementations. The third element (if present) is a line offset for adjusting displayed line numbers.
§Example
let mut buffer = Vec::new();
Report::new()
.with_title(Level::Warning, "Deprecated")
.with_label(0..3)
.render_to_writer(&mut buffer, "let x = 1;")?;
assert!(!buffer.is_empty());