Skip to content
Merged
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
22 changes: 12 additions & 10 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn simple() -> String {
}
}"#;
let message = &[
Group::with_title(Level::ERROR.title("mismatched types").id("E0308")).element(
Group::with_title(Level::ERROR.primary_title("mismatched types").id("E0308")).element(
Snippet::source(source)
.line_start(51)
.path("src/format.rs")
Expand Down Expand Up @@ -69,15 +69,17 @@ fn fold(bencher: divan::Bencher<'_, '_>, context: usize) {
(input, span)
})
.bench_values(|(input, span)| {
let message = &[
Group::with_title(Level::ERROR.title("mismatched types").id("E0308")).element(
Snippet::source(&input).path("src/format.rs").annotation(
AnnotationKind::Context
.span(span)
.label("expected `Option<String>` because of return type"),
),
),
];
let message =
&[
Group::with_title(Level::ERROR.primary_title("mismatched types").id("E0308"))
.element(
Snippet::source(&input).path("src/format.rs").annotation(
AnnotationKind::Context
.span(span)
.label("expected `Option<String>` because of return type"),
),
),
];

let renderer = Renderer::plain();
let rendered = renderer.render(message);
Expand Down
2 changes: 1 addition & 1 deletion examples/custom_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub static C: u32 = 0 - 1;
let message = &[Group::with_title(
Level::ERROR
.with_name(Some("error: internal compiler error"))
.title("could not evaluate static initializer")
.primary_title("could not evaluate static initializer")
.id("E0080"),
)
.element(
Expand Down
4 changes: 2 additions & 2 deletions examples/custom_level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fn main() {
let message = &[
Group::with_title(
Level::ERROR
.title("`break` with value from a `while` loop")
.primary_title("`break` with value from a `while` loop")
.id("E0571"),
)
.element(
Expand All @@ -53,7 +53,7 @@ fn main() {
Group::with_title(
Level::HELP
.with_name(Some("suggestion"))
.title("use `break` on its own without a value inside this `while` loop"),
.primary_title("use `break` on its own without a value inside this `while` loop"),
)
.element(
Snippet::source(source)
Expand Down
2 changes: 1 addition & 1 deletion examples/expected_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ fn main() {
range: <22, 25>,"#;
let message =
&[
Group::with_title(Level::ERROR.title("expected type, found `22`")).element(
Group::with_title(Level::ERROR.primary_title("expected type, found `22`")).element(
Snippet::source(source)
.line_start(26)
.path("examples/footer.rs")
Expand Down
4 changes: 2 additions & 2 deletions examples/footer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ use annotate_snippets::{AnnotationKind, Group, Level, Renderer, Snippet};
fn main() {
let message =
&[
Group::with_title(Level::ERROR.title("mismatched types").id("E0308")).element(
Group::with_title(Level::ERROR.primary_title("mismatched types").id("E0308")).element(
Snippet::source(" slices: vec![\"A\",")
.line_start(13)
.path("src/multislice.rs")
.annotation(AnnotationKind::Primary.span(21..24).label(
"expected struct `annotate_snippets::snippet::Slice`, found reference",
)),
),
Group::with_title(Level::NOTE.title(
Group::with_title(Level::NOTE.primary_title(
"expected type: `snippet::Annotation`\n found type: `__&__snippet::Annotation`",
)),
];
Expand Down
2 changes: 1 addition & 1 deletion examples/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fn main() {
}
}"#;
let message = &[
Group::with_title(Level::ERROR.title("mismatched types").id("E0308")).element(
Group::with_title(Level::ERROR.primary_title("mismatched types").id("E0308")).element(
Snippet::source(source)
.line_start(51)
.path("src/format.rs")
Expand Down
4 changes: 2 additions & 2 deletions examples/highlight_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ fn main() {
);

let message = &[
Group::with_title(Level::ERROR.title("mismatched types").id("E0308"))
Group::with_title(Level::ERROR.primary_title("mismatched types").id("E0308"))
.element(
Snippet::source(source)
.path("$DIR/highlighting.rs")
Expand All @@ -50,7 +50,7 @@ fn main() {
),
)
.element(Level::NOTE.message(&message)),
Group::with_title(Level::NOTE.title("function defined here")).element(
Group::with_title(Level::NOTE.primary_title("function defined here")).element(
Snippet::source(source)
.path("$DIR/highlighting.rs")
.annotation(AnnotationKind::Context.span(200..333).label(""))
Expand Down
2 changes: 1 addition & 1 deletion examples/highlight_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const CON: Vec<i32> = vec![1, 2, 3]; //~ ERROR E0010
//~| ERROR cannot call non-const method
fn main() {}
"#;
let message = &[Group::with_title(Level::ERROR.title("allocations are not allowed in constants")
let message = &[Group::with_title(Level::ERROR.primary_title("allocations are not allowed in constants")
.id("E0010"))
.element(
Snippet::source(source)
Expand Down
2 changes: 1 addition & 1 deletion examples/id_hyperlink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ fn main() {
"#;
let message = &[Group::with_title(
Level::ERROR
.title("mismatched types")
.primary_title("mismatched types")
.id("E0308")
.id_url("https://doc.rust-lang.org/error_codes/E0308.html"),
)
Expand Down
28 changes: 15 additions & 13 deletions examples/multislice.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
use annotate_snippets::{Annotation, Group, Level, Renderer, Snippet};

fn main() {
let message = &[Group::with_title(Level::ERROR.title("mismatched types"))
.element(
Snippet::<Annotation<'_>>::source("Foo")
.line_start(51)
.fold(false)
.path("src/format.rs"),
)
.element(
Snippet::<Annotation<'_>>::source("Faa")
.line_start(129)
.fold(false)
.path("src/display.rs"),
)];
let message = &[
Group::with_title(Level::ERROR.primary_title("mismatched types"))
.element(
Snippet::<Annotation<'_>>::source("Foo")
.line_start(51)
.fold(false)
.path("src/format.rs"),
)
.element(
Snippet::<Annotation<'_>>::source("Faa")
.line_start(129)
.fold(false)
.path("src/display.rs"),
),
];

let renderer = Renderer::styled();
anstream::println!("{}", renderer.render(message));
Expand Down
29 changes: 12 additions & 17 deletions examples/struct_name_as_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,18 @@ fn main() {
field6: usize,
}
"#;
let message =
&[
Group::with_title(
Level::ERROR.title("functions are not allowed in struct definitions"),
)
.element(
Snippet::source(source)
.path("$DIR/struct_name_as_context.rs")
.annotation(AnnotationKind::Primary.span(91..102))
.annotation(AnnotationKind::Visible.span(0..8)),
)
.element(
Level::HELP.message(
"unlike in C++, Java, and C#, functions are declared in `impl` blocks",
),
),
];
let message = &[Group::with_title(
Level::ERROR.primary_title("functions are not allowed in struct definitions"),
)
.element(
Snippet::source(source)
.path("$DIR/struct_name_as_context.rs")
.annotation(AnnotationKind::Primary.span(91..102))
.annotation(AnnotationKind::Visible.span(0..8)),
)
.element(
Level::HELP.message("unlike in C++, Java, and C#, functions are declared in `impl` blocks"),
)];

let renderer = Renderer::styled();
anstream::println!("{}", renderer.render(message));
Expand Down
39 changes: 32 additions & 7 deletions src/level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,16 @@ impl<'a> Level<'a> {
}

impl<'a> Level<'a> {
/// A text [`Element`][crate::Element] to start a [`Group`][crate::Group]
/// Creates a [`Title`] that has bolded text, and is
/// intended to be used with the "primary" (first)
/// [`Group`][crate::Group] in a [`Report`][crate::Report].
///
/// See [`Group::with_title`][crate::Group::with_title]
///
/// <div class="warning">
///
/// Text passed to this function is considered "untrusted input", as such
/// all text is passed through a normalization function. Pre-styled text is
/// all text is passed through a normalization function. Styled text is
/// not allowed to be passed to this function.
///
/// </div>
Expand All @@ -70,22 +72,45 @@ impl<'a> Level<'a> {
/// ```rust
/// # use annotate_snippets::{Group, Snippet, AnnotationKind, Level};
/// let input = &[
/// Group::with_title(Level::ERROR.title("mismatched types").id("E0308"))
/// Group::with_title(Level::ERROR.primary_title("mismatched types").id("E0308"))
/// ];
/// ```
pub fn title(self, text: impl Into<Cow<'a, str>>) -> Title<'a> {
pub fn primary_title(self, text: impl Into<Cow<'a, str>>) -> Title<'a> {
Title {
level: self,
id: None,
text: text.into(),
allows_styling: false,
}
}

/// Creates a [`Title`] that is allowed to be styled, for more info see the
/// warning below.
///
/// See [`Group::with_title`][crate::Group::with_title]
///
/// <div class="warning">
///
/// Text passed to this function is allowed to be styled, as such all
/// text is considered "trusted input" and has no normalizations applied to
/// it. [`normalize_untrusted_str`](crate::normalize_untrusted_str) can be
/// used to normalize untrusted text before it is passed to this function.
///
/// </div>
pub fn secondary_title(self, text: impl Into<Cow<'a, str>>) -> Title<'a> {
Title {
level: self,
id: None,
text: text.into(),
allows_styling: true,
}
}

/// A text [`Element`][crate::Element] in a [`Group`][crate::Group]
///
/// <div class="warning">
///
/// Text passed to this function is allowed to be pre-styled, as such all
/// Text passed to this function is allowed to be styled, as such all
/// text is considered "trusted input" and has no normalizations applied to
/// it. [`normalize_untrusted_str`](crate::normalize_untrusted_str) can be
/// used to normalize untrusted text before it is passed to this function.
Expand All @@ -97,7 +122,7 @@ impl<'a> Level<'a> {
/// ```rust
/// # use annotate_snippets::{Group, Snippet, AnnotationKind, Level};
/// let input = &[
/// Group::with_title(Level::ERROR.title("mismatched types").id("E0308"))
/// Group::with_title(Level::ERROR.primary_title("mismatched types").id("E0308"))
/// .element(
/// Level::NOTE
/// .no_name()
Expand Down Expand Up @@ -166,7 +191,7 @@ impl<'a> Level<'a> {
/// let s: &str = include_bytes!("file.txt"); //~ ERROR mismatched types
/// }"#;
/// let input = &[
/// Group::with_title(Level::ERROR.title("mismatched types").id("E0308"))
/// Group::with_title(Level::ERROR.primary_title("mismatched types").id("E0308"))
/// .element(
/// Snippet::source(source)
/// .path("$DIR/mismatched-types.rs")
Expand Down
12 changes: 6 additions & 6 deletions src/renderer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
//!
//! Group::with_title(
//! Level::ERROR
//! .title("unresolved import `baz::zed`")
//! .primary_title("unresolved import `baz::zed`")
//! .id("E0432")
//! )
//! .element(
Expand Down Expand Up @@ -596,7 +596,7 @@ impl Renderer {
label_width
});

let (title_str, style) = if title.is_pre_styled() {
let (title_str, style) = if title.allows_styling() {
(title.text().to_owned(), ElementStyle::NoStyle)
} else {
(normalize_whitespace(title.text()), title_element_style)
Expand Down Expand Up @@ -2609,7 +2609,7 @@ trait MessageOrTitle {
fn level(&self) -> &Level<'_>;
fn id(&self) -> Option<&Id<'_>>;
fn text(&self) -> &str;
fn is_pre_styled(&self) -> bool;
fn allows_styling(&self) -> bool;
}

impl MessageOrTitle for Title<'_> {
Expand All @@ -2622,8 +2622,8 @@ impl MessageOrTitle for Title<'_> {
fn text(&self) -> &str {
self.text.as_ref()
}
fn is_pre_styled(&self) -> bool {
false
fn allows_styling(&self) -> bool {
self.allows_styling
}
}

Expand All @@ -2637,7 +2637,7 @@ impl MessageOrTitle for Message<'_> {
fn text(&self) -> &str {
self.text.as_ref()
}
fn is_pre_styled(&self) -> bool {
fn allows_styling(&self) -> bool {
true
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/snippet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,13 @@ pub struct Padding;

/// A text [`Element`] to start a [`Group`]
///
/// See [`Level::title`] to create this.
/// See [`Level::primary_title`] to create this.
#[derive(Clone, Debug)]
pub struct Title<'a> {
pub(crate) level: Level<'a>,
pub(crate) id: Option<Id<'a>>,
pub(crate) text: Cow<'a, str>,
pub(crate) allows_styling: bool,
}

impl<'a> Title<'a> {
Expand Down Expand Up @@ -433,7 +434,7 @@ impl<'a> Patch<'a> {
/// ```rust
/// # use annotate_snippets::{Group, Snippet, AnnotationKind, Level, Origin};
/// let input = &[
/// Group::with_title(Level::ERROR.title("mismatched types").id("E0308"))
/// Group::with_title(Level::ERROR.primary_title("mismatched types").id("E0308"))
/// .element(
/// Origin::path("$DIR/mismatched-types.rs")
/// )
Expand Down
2 changes: 1 addition & 1 deletion tests/color/ann_eof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use snapbox::{assert_data_eq, file};
#[test]
fn case() {
let input = &[
Group::with_title(Level::ERROR.title("expected `.`, `=`")).element(
Group::with_title(Level::ERROR.primary_title("expected `.`, `=`")).element(
Snippet::source("asdf")
.path("Cargo.toml")
.line_start(1)
Expand Down
2 changes: 1 addition & 1 deletion tests/color/ann_insertion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use snapbox::{assert_data_eq, file};
#[test]
fn case() {
let input = &[
Group::with_title(Level::ERROR.title("expected `.`, `=`")).element(
Group::with_title(Level::ERROR.primary_title("expected `.`, `=`")).element(
Snippet::source("asf")
.path("Cargo.toml")
.line_start(1)
Expand Down
2 changes: 1 addition & 1 deletion tests/color/ann_multiline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fn case() {

let input = &[Group::with_title(
Level::ERROR
.title("pattern does not mention fields `lineno`, `content`")
.primary_title("pattern does not mention fields `lineno`, `content`")
.id("E0027"),
)
.element(
Expand Down
Loading
Loading