Skip to content

fix!: Iterate on the API #198

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Apr 16, 2025
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
6 changes: 3 additions & 3 deletions benches/bench.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use annotate_snippets::{level::Level, AnnotationKind, Group, Renderer, Snippet};
use annotate_snippets::{AnnotationKind, Group, Level, Renderer, Snippet};

#[divan::bench]
fn simple() -> String {
Expand All @@ -24,7 +24,7 @@ fn simple() -> String {
_ => continue,
}
}"#;
let message = Level::ERROR.message("mismatched types").id("E0308").group(
let message = Level::ERROR.header("mismatched types").id("E0308").group(
Group::new().element(
Snippet::source(source)
.line_start(51)
Expand Down Expand Up @@ -69,7 +69,7 @@ fn fold(bencher: divan::Bencher<'_, '_>, context: usize) {
(input, span)
})
.bench_values(|(input, span)| {
let message = Level::ERROR.message("mismatched types").id("E0308").group(
let message = Level::ERROR.header("mismatched types").id("E0308").group(
Group::new().element(
Snippet::source(&input)
.fold(true)
Expand Down
4 changes: 2 additions & 2 deletions examples/custom_error.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use annotate_snippets::renderer::OutputTheme;
use annotate_snippets::{level::Level, AnnotationKind, Group, Renderer, Snippet};
use annotate_snippets::{AnnotationKind, Group, Level, Renderer, Snippet};

fn main() {
let source = r#"//@ compile-flags: -Ztreat-err-as-bug
Expand All @@ -17,7 +17,7 @@ pub static C: u32 = 0 - 1;
"#;
let message = Level::ERROR
.text(Some("error: internal compiler error"))
.message("could not evaluate static initializer")
.header("could not evaluate static initializer")
.id("E0080")
.group(
Group::new().element(
Expand Down
4 changes: 2 additions & 2 deletions examples/custom_level.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use annotate_snippets::renderer::OutputTheme;
use annotate_snippets::{level::Level, AnnotationKind, Group, Patch, Renderer, Snippet};
use annotate_snippets::{AnnotationKind, Group, Level, Patch, Renderer, Snippet};

fn main() {
let source = r#"// Regression test for issue #114529
Expand Down Expand Up @@ -30,7 +30,7 @@ fn main() {
}
"#;
let message = Level::ERROR
.message("`break` with value from a `while` loop")
.header("`break` with value from a `while` loop")
.id("E0571")
.group(
Group::new().element(
Expand Down
4 changes: 2 additions & 2 deletions examples/expected_type.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use annotate_snippets::{level::Level, AnnotationKind, Group, Renderer, Snippet};
use annotate_snippets::{AnnotationKind, Group, Level, Renderer, Snippet};

fn main() {
let source = r#" annotations: vec![SourceAnnotation {
label: "expected struct `annotate_snippets::snippet::Slice`, found reference"
,
range: <22, 25>,"#;
let message =
Level::ERROR.message("expected type, found `22`").group(
Level::ERROR.header("expected type, found `22`").group(
Group::new().element(
Snippet::source(source)
.line_start(26)
Expand Down
4 changes: 2 additions & 2 deletions examples/footer.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use annotate_snippets::{level::Level, AnnotationKind, Group, Renderer, Snippet};
use annotate_snippets::{AnnotationKind, Group, Level, Renderer, Snippet};

fn main() {
let message = Level::ERROR
.message("mismatched types")
.header("mismatched types")
.id("E0308")
.group(
Group::new().element(
Expand Down
4 changes: 2 additions & 2 deletions examples/format.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use annotate_snippets::{level::Level, AnnotationKind, Group, Renderer, Snippet};
use annotate_snippets::{AnnotationKind, Group, Level, Renderer, Snippet};

fn main() {
let source = r#") -> Option<String> {
Expand All @@ -23,7 +23,7 @@ fn main() {
_ => continue,
}
}"#;
let message = Level::ERROR.message("mismatched types").id("E0308").group(
let message = Level::ERROR.header("mismatched types").id("E0308").group(
Group::new().element(
Snippet::source(source)
.line_start(51)
Expand Down
4 changes: 2 additions & 2 deletions examples/highlight_source.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use annotate_snippets::{level::Level, AnnotationKind, Group, Renderer, Snippet};
use annotate_snippets::{AnnotationKind, Group, Level, Renderer, Snippet};

fn main() {
let source = r#"//@ compile-flags: -Z teach
Expand All @@ -10,7 +10,7 @@ const CON: Vec<i32> = vec![1, 2, 3]; //~ ERROR E0010
fn main() {}
"#;
let message = Level::ERROR
.message("allocations are not allowed in constants")
.header("allocations are not allowed in constants")
.id("E0010")
.group(
Group::new()
Expand Down
4 changes: 2 additions & 2 deletions examples/highlight_title.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use annotate_snippets::{level::Level, AnnotationKind, Group, Renderer, Snippet};
use annotate_snippets::{AnnotationKind, Group, Level, Renderer, Snippet};
use anstyle::Effects;

fn main() {
Expand Down Expand Up @@ -43,7 +43,7 @@ fn main() {
magenta.render_reset()
);

let message = Level::ERROR.message("mismatched types").id("E0308").group(
let message = Level::ERROR.header("mismatched types").id("E0308").group(
Group::new()
.element(
Snippet::source(source)
Expand Down
4 changes: 2 additions & 2 deletions examples/multislice.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use annotate_snippets::{level::Level, Annotation, Group, Renderer, Snippet};
use annotate_snippets::{Annotation, Group, Level, Renderer, Snippet};

fn main() {
let message = Level::ERROR.message("mismatched types").group(
let message = Level::ERROR.header("mismatched types").group(
Group::new()
.element(
Snippet::<Annotation<'_>>::source("Foo")
Expand Down
36 changes: 23 additions & 13 deletions src/level.rs
Original file line number Diff line number Diff line change
@@ -1,59 +1,61 @@
//! [`Level`] constants for easy importing

use crate::renderer::stylesheet::Stylesheet;
use crate::snippet::{ERROR_TXT, HELP_TXT, INFO_TXT, NOTE_TXT, WARNING_TXT};
use crate::{Element, Group, Message, Title};
use anstyle::Style;

/// Default `error:` [`Level`]
pub const ERROR: Level<'_> = Level {
name: None,
level: LevelInner::Error,
};

/// Default `warning:` [`Level`]
pub const WARNING: Level<'_> = Level {
name: None,
level: LevelInner::Warning,
};

/// Default `info:` [`Level`]
pub const INFO: Level<'_> = Level {
name: None,
level: LevelInner::Info,
};

/// Default `note:` [`Level`]
pub const NOTE: Level<'_> = Level {
name: None,
level: LevelInner::Note,
};

/// Default `help:` [`Level`]
pub const HELP: Level<'_> = Level {
name: None,
level: LevelInner::Help,
};

/// [`Message`] or [`Title`] severity level
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Level<'a> {
pub(crate) name: Option<Option<&'a str>>,
pub(crate) level: LevelInner,
}

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum Level2<'a> {
Builtin(LevelInner),
Custom {
name: Option<&'a str>,
level: LevelInner,
},
None,
}

impl<'a> Level<'a> {
pub const ERROR: Level<'a> = ERROR;
pub const WARNING: Level<'a> = WARNING;
pub const INFO: Level<'a> = INFO;
pub const NOTE: Level<'a> = NOTE;
pub const HELP: Level<'a> = HELP;

/// <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
/// not allowed to be passed to this function.
///
/// </div>
pub fn text(self, text: Option<&'a str>) -> Level<'a> {
Level {
name: Some(text),
Expand All @@ -63,24 +65,32 @@ impl<'a> Level<'a> {
}

impl<'a> Level<'a> {
/// <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
/// not allowed to be passed to this function.
pub fn message(self, title: &'a str) -> Message<'a> {
///
/// </div>
pub fn header(self, header: &'a str) -> Message<'a> {
Message {
id: None,
groups: vec![Group::new().element(Element::Title(Title {
level: self,
title,
title: header,
primary: true,
}))],
}
}

/// <div class="warning">
///
/// Text passed to this function is allowed to be pre-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 title(self, title: &'a str) -> Title<'a> {
Title {
level: self,
Expand All @@ -107,7 +117,7 @@ impl<'a> Level<'a> {
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum LevelInner {
pub(crate) enum LevelInner {
Error,
Warning,
Info,
Expand Down
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ pub fn normalize_untrusted_str(s: &str) -> String {
renderer::normalize_whitespace(s)
}

#[doc(inline)]
pub use level::Level;
#[doc(inline)]
pub use renderer::Renderer;
pub use snippet::ColumnSeparator;
pub use snippet::*;
30 changes: 15 additions & 15 deletions src/renderer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! # Example
//! ```
//! use annotate_snippets::*;
//! use annotate_snippets::level::Level;
//! use annotate_snippets::Level;
//!
//! let source = r#"
//! use baz::zed::bar;
Expand All @@ -19,7 +19,7 @@
//! }
//! "#;
//! Level::ERROR
//! .message("unresolved import `baz::zed`")
//! .header("unresolved import `baz::zed`")
//! .id("E0432")
//! .group(
//! Group::new().element(
Expand Down Expand Up @@ -101,7 +101,7 @@ impl Renderer {
info: BRIGHT_BLUE.effects(Effects::BOLD),
note: AnsiColor::BrightGreen.on_default().effects(Effects::BOLD),
help: AnsiColor::BrightCyan.on_default().effects(Effects::BOLD),
line_no: BRIGHT_BLUE.effects(Effects::BOLD),
line_num: BRIGHT_BLUE.effects(Effects::BOLD),
emphasis: if USE_WINDOWS_COLORS {
AnsiColor::BrightWhite.on_default()
} else {
Expand Down Expand Up @@ -178,8 +178,8 @@ impl Renderer {
}

/// Set the output style for line numbers
pub const fn line_no(mut self, style: Style) -> Self {
self.stylesheet.line_no = style;
pub const fn line_num(mut self, style: Style) -> Self {
self.stylesheet.line_num = style;
self
}

Expand Down Expand Up @@ -383,7 +383,7 @@ impl Renderer {
self.render_origin(buffer, max_line_num_len, origin);
last_was_suggestion = false;
}
Element::ColumnSeparator(_) => {
Element::Padding(_) => {
self.draw_col_separator_no_space(
buffer,
buffer.num_lines(),
Expand Down Expand Up @@ -430,7 +430,7 @@ impl Renderer {

let (has_primary_spans, has_span_labels) =
next_section.map_or((false, false), |s| match s {
Element::Title(_) | Element::ColumnSeparator(_) => (false, false),
Element::Title(_) | Element::Padding(_) => (false, false),
Element::Cause(cause) => (
cause.markers.iter().any(|m| m.kind.is_primary()),
cause.markers.iter().any(|m| m.label.is_some()),
Expand Down Expand Up @@ -1523,7 +1523,7 @@ impl Renderer {
}
if suggestion.origin != primary_origin {
if let Some(origin) = suggestion.origin {
let (loc, _) = sm.span_to_locations(parts[0].range.clone());
let (loc, _) = sm.span_to_locations(parts[0].span.clone());
// --> file.rs:line:col
// |
let arrow = self.file_start();
Expand Down Expand Up @@ -1563,8 +1563,8 @@ impl Renderer {
row_num += 1;
}

let file_lines = sm.span_to_lines(parts[0].range.clone());
let (line_start, line_end) = sm.span_to_locations(parts[0].range.clone());
let file_lines = sm.span_to_lines(parts[0].span.clone());
let (line_start, line_end) = sm.span_to_locations(parts[0].span.clone());
let mut lines = complete.lines();
if lines.clone().next().is_none() {
// Account for a suggestion to completely remove a line(s) with whitespace (#94192).
Expand Down Expand Up @@ -1697,8 +1697,8 @@ impl Renderer {
// already existing code, despite the colors and UI elements.
// We special case `#[derive(_)]\n` and other attribute suggestions, because those
// are the ones where context is most useful.
let file_lines = sm.span_to_lines(parts[0].range.end..parts[0].range.end);
let (lo, _) = sm.span_to_locations(parts[0].range.clone());
let file_lines = sm.span_to_lines(parts[0].span.end..parts[0].span.end);
let (lo, _) = sm.span_to_locations(parts[0].span.clone());
let line_num = lo.line;
if let Some(line) = sm.get_line(line_num) {
let line = normalize_whitespace(line);
Expand All @@ -1724,7 +1724,7 @@ impl Renderer {
show_code_change
{
for part in parts {
let (span_start, span_end) = sm.span_to_locations(part.range.clone());
let (span_start, span_end) = sm.span_to_locations(part.span.clone());
let span_start_pos = span_start.display;
let span_end_pos = span_end.display;

Expand Down Expand Up @@ -1764,7 +1764,7 @@ impl Renderer {
let padding: usize = max_line_num_len + 3;
for p in underline_start..underline_end {
if matches!(show_code_change, DisplaySuggestion::Underline)
&& is_different(sm, part.replacement, part.range.clone())
&& is_different(sm, part.replacement, part.span.clone())
{
// If this is a replacement, underline with `~`, if this is an addition
// underline with `+`.
Expand Down Expand Up @@ -2665,7 +2665,7 @@ impl ElementStyle {
ElementStyle::Addition => stylesheet.addition,
ElementStyle::Removal => stylesheet.removal,
ElementStyle::LineAndColumn => stylesheet.none,
ElementStyle::LineNumber => stylesheet.line_no,
ElementStyle::LineNumber => stylesheet.line_num,
ElementStyle::Quotation => stylesheet.none,
ElementStyle::MainHeaderMsg => stylesheet.emphasis,
ElementStyle::UnderlinePrimary | ElementStyle::LabelPrimary => level.style(stylesheet),
Expand Down
Loading