pub trait Render {
// Required methods
fn render(&self, src: &str) -> String;
fn render_indexed(&self, src: &str, index: &LineIndex) -> String;
}Expand description
Rendering of a diagnostic-bearing value as a rustc-style snippet of its
source. Implemented for Diagnostic and crate::Error.
Display stays the compact one-line form; Render::render draws the
code, message, the labelled source lines with carets, help, path, and
suggested fixes:
error[Y0027]: `: ` inside an unquoted value starts a nested mapping, which cannot begin on this line
--> 1:4
|
1 | a: b: c
| ^^^^
| - this `: ` starts a mapping
|
= help: to keep the `: ` as text, quote the whole value; …
= suggestion: quote the value: replace `b: c` with `'b: c'`§What is shown
- Every label’s lines, in line order; lines that are not adjacent are
separated by
.... A label spanning several lines is drawn on its first line (to the end of the line) and on its last line (from the start of the line), with its message on the last one. - Primary labels are underlined with
^, secondary ones with-; an empty span (e.g. at the end of the input) gets one caret. - Tabs are shown as four spaces; wide characters (CJK, emoji) count two
columns and combining marks none, so carets line up in a terminal.
Control characters, bidirectional overrides and Unicode line
separators are shown as
\u{FFFD}so they cannot reorder or break the snippet.\n,\r\nand a lone\rall end a line (§5.4). - A line wider than 100 columns is cut to a window around its
labels, marked with
...on the cut side.
§Cost
With an index (Render::render_indexed) a call costs O(labels ×
(log n + 100)) — the lines shown, never the input. Line starts
and ends are found by scans capped at 1024 bytes, so a
100 MB single-line input costs the same as a short line.
Render::render on a Diagnostic builds a LineIndex first
(one O(n) pass); to render many diagnostics of one source, build the
index once and use render_indexed. Error::render
needs no index: an error already knows the line and column of its
primary span, and other labels are numbered by counting line breaks
from it.
§Robustness
Rendering never panics: spans past the end are clamped to it, spans
off char boundaries are moved back to one, inverted spans are read
as empty, and a LineIndex built from a different text only gives
wrong line numbers.
use oneyaml::{Document, Render};
let src = "a: b: c\n";
let parsed = Document::parse_recovering(src);
let snippet = parsed.diagnostics()[0].render(src);
assert!(snippet.starts_with("error[Y0027]"));
assert!(snippet.contains("1 | a: b: c"));To render many diagnostics of one source (a recovering parse’s, or the
warnings from_str skips), build its LineIndex once and use
Render::render_indexed:
use oneyaml::{Document, LineIndex, Render};
let src = "%YAML 1.1\n---\nquote: 'it's'\n";
let parsed = Document::parse_recovering(src);
let index = LineIndex::new(src);
let shown: Vec<String> = parsed
.diagnostics()
.iter()
.map(|d| d.render_indexed(src, &index))
.collect();
assert!(shown[0].starts_with("warning[Y1000]"));
assert!(shown[1].contains("write `''` for a literal `'`"));
// The strict entry points keep the warnings recorded before the error.
let err = oneyaml::from_str::<oneyaml::Value>(src).err().ok_or("expected an error")?;
assert_eq!(err.warnings()[0].code, oneyaml::code::YAML_VERSION_1_1);
assert!(err.render_indexed(src, &index).contains("3 | quote: 'it's'"));With the miette feature, DiagnosticReport wraps any Diagnostic
(with its source) as a miette::Diagnostic.
Required Methods§
Sourcefn render(&self, src: &str) -> String
fn render(&self, src: &str) -> String
The snippet for src, the text the spans point into. Never panics,
whatever src is (see the trait docs for the cost).
For a Diagnostic this builds a LineIndex of src on every
call (O(n)): to render several diagnostics of one text, build the
index once and call Render::render_indexed, or use
Document::render_diagnostics
/ Parsed::render_diagnostics.
Sourcefn render_indexed(&self, src: &str, index: &LineIndex) -> String
fn render_indexed(&self, src: &str, index: &LineIndex) -> String
Render::render with line numbers from index, an index of
src built once for many calls: O(lines shown), never O(input).
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".