Skip to content

Commit 172ba75

Browse files
authored
Merge pull request #245 from epage/docs
docs: Clarify usage
2 parents 1d2ae61 + e2b0339 commit 172ba75

File tree

8 files changed

+131
-47
lines changed

8 files changed

+131
-47
lines changed

examples/highlight_message.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use annotate_snippets::{AnnotationKind, Group, Level, Renderer, Snippet};
2+
use anstyle::AnsiColor;
23
use anstyle::Effects;
4+
use anstyle::Style;
35

46
fn main() {
57
let source = r#"// Make sure "highlighted" code is colored purple
@@ -25,20 +27,10 @@ fn main() {
2527
query(wrapped_fn);
2628
}"#;
2729

28-
let magenta = annotate_snippets::renderer::AnsiColor::Magenta
29-
.on_default()
30-
.effects(Effects::BOLD);
30+
const MAGENTA: Style = AnsiColor::Magenta.on_default().effects(Effects::BOLD);
3131
let message = format!(
32-
"expected fn pointer `{}for<'a>{} fn(Box<{}(dyn Any + Send + 'a){}>) -> Pin<_>`
33-
found fn item `fn(Box<{}(dyn Any + Send + 'static){}>) -> Pin<_> {}{{wrapped_fn}}{}`",
34-
magenta.render(),
35-
magenta.render_reset(),
36-
magenta.render(),
37-
magenta.render_reset(),
38-
magenta.render(),
39-
magenta.render_reset(),
40-
magenta.render(),
41-
magenta.render_reset()
32+
"expected fn pointer `{MAGENTA}for<'a>{MAGENTA:#} fn(Box<{MAGENTA}(dyn Any + Send + 'a){MAGENTA:#}>) -> Pin<_>`
33+
found fn item `fn(Box<{MAGENTA}(dyn Any + Send + 'static){MAGENTA:#}>) -> Pin<_> {MAGENTA}{{wrapped_fn}}{MAGENTA:#}`",
4234
);
4335

4436
let message = &[

src/level.rs

Lines changed: 88 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,40 +36,20 @@ pub const HELP: Level<'_> = Level {
3636
level: LevelInner::Help,
3737
};
3838

39-
/// [`Title`] severity level
39+
/// Severity level for [`Title`]s and [`Message`]s
4040
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
4141
pub struct Level<'a> {
4242
pub(crate) name: Option<Option<Cow<'a, str>>>,
4343
pub(crate) level: LevelInner,
4444
}
4545

46+
/// # Constructors
4647
impl<'a> Level<'a> {
4748
pub const ERROR: Level<'a> = ERROR;
4849
pub const WARNING: Level<'a> = WARNING;
4950
pub const INFO: Level<'a> = INFO;
5051
pub const NOTE: Level<'a> = NOTE;
5152
pub const HELP: Level<'a> = HELP;
52-
53-
/// Replace the name describing this [`Level`]
54-
///
55-
/// <div class="warning">
56-
///
57-
/// Text passed to this function is considered "untrusted input", as such
58-
/// all text is passed through a normalization function. Pre-styled text is
59-
/// not allowed to be passed to this function.
60-
///
61-
/// </div>
62-
pub fn with_name(self, name: impl Into<OptionCow<'a>>) -> Level<'a> {
63-
Level {
64-
name: Some(name.into().0),
65-
level: self.level,
66-
}
67-
}
68-
69-
/// Do not show the [`Level`]s name
70-
pub fn no_name(self) -> Level<'a> {
71-
self.with_name(None::<&str>)
72-
}
7353
}
7454

7555
impl<'a> Level<'a> {
@@ -84,6 +64,15 @@ impl<'a> Level<'a> {
8464
/// not allowed to be passed to this function.
8565
///
8666
/// </div>
67+
///
68+
/// # Example
69+
///
70+
/// ```rust
71+
/// # use annotate_snippets::{Group, Snippet, AnnotationKind, Level};
72+
/// let input = &[
73+
/// Group::with_title(Level::ERROR.title("mismatched types").id("E0308"))
74+
/// ];
75+
/// ```
8776
pub fn title(self, text: impl Into<Cow<'a, str>>) -> Title<'a> {
8877
Title {
8978
level: self,
@@ -102,6 +91,20 @@ impl<'a> Level<'a> {
10291
/// used to normalize untrusted text before it is passed to this function.
10392
///
10493
/// </div>
94+
///
95+
/// # Example
96+
///
97+
/// ```rust
98+
/// # use annotate_snippets::{Group, Snippet, AnnotationKind, Level};
99+
/// let input = &[
100+
/// Group::with_title(Level::ERROR.title("mismatched types").id("E0308"))
101+
/// .element(
102+
/// Level::NOTE
103+
/// .no_name()
104+
/// .message("expected reference `&str`\nfound reference `&'static [u8; 0]`"),
105+
/// ),
106+
/// ];
107+
/// ```
105108
pub fn message(self, text: impl Into<Cow<'a, str>>) -> Message<'a> {
106109
Message {
107110
level: self,
@@ -126,6 +129,69 @@ impl<'a> Level<'a> {
126129
}
127130
}
128131

132+
/// # Customize the `Level`
133+
impl<'a> Level<'a> {
134+
/// Replace the name describing this [`Level`]
135+
///
136+
/// <div class="warning">
137+
///
138+
/// Text passed to this function is considered "untrusted input", as such
139+
/// all text is passed through a normalization function. Pre-styled text is
140+
/// not allowed to be passed to this function.
141+
///
142+
/// </div>
143+
///
144+
/// # Example
145+
///
146+
/// ```rust
147+
#[doc = include_str!("../examples/custom_level.rs")]
148+
/// ```
149+
#[doc = include_str!("../examples/custom_level.svg")]
150+
pub fn with_name(self, name: impl Into<OptionCow<'a>>) -> Level<'a> {
151+
Level {
152+
name: Some(name.into().0),
153+
level: self.level,
154+
}
155+
}
156+
157+
/// Do not show the [`Level`]s name
158+
///
159+
/// # Example
160+
///
161+
/// ```rust
162+
/// # use annotate_snippets::{Group, Snippet, AnnotationKind, Level};
163+
///let source = r#"fn main() {
164+
/// let b: &[u8] = include_str!("file.txt"); //~ ERROR mismatched types
165+
/// let s: &str = include_bytes!("file.txt"); //~ ERROR mismatched types
166+
/// }"#;
167+
/// let input = &[
168+
/// Group::with_title(Level::ERROR.title("mismatched types").id("E0308"))
169+
/// .element(
170+
/// Snippet::source(source)
171+
/// .path("$DIR/mismatched-types.rs")
172+
/// .annotation(
173+
/// AnnotationKind::Primary
174+
/// .span(105..131)
175+
/// .label("expected `&str`, found `&[u8; 0]`"),
176+
/// )
177+
/// .annotation(
178+
/// AnnotationKind::Context
179+
/// .span(98..102)
180+
/// .label("expected due to this"),
181+
/// ),
182+
/// )
183+
/// .element(
184+
/// Level::NOTE
185+
/// .no_name()
186+
/// .message("expected reference `&str`\nfound reference `&'static [u8; 0]`"),
187+
/// ),
188+
/// ];
189+
/// ```
190+
pub fn no_name(self) -> Level<'a> {
191+
self.with_name(None::<&str>)
192+
}
193+
}
194+
129195
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
130196
pub(crate) enum LevelInner {
131197
Error,

src/renderer/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ impl Renderer {
484484
}
485485

486486
if let Some(path) = &cause.path {
487-
let mut origin = Origin::new(path.as_ref());
487+
let mut origin = Origin::path(path.as_ref());
488488
origin.primary = true;
489489

490490
let source_map = SourceMap::new(&cause.source, cause.line_start);
@@ -719,7 +719,7 @@ impl Renderer {
719719
is_cont: bool,
720720
) {
721721
if let Some(path) = &snippet.path {
722-
let mut origin = Origin::new(path.as_ref());
722+
let mut origin = Origin::path(path.as_ref());
723723
// print out the span location and spacer before we print the annotated source
724724
// to do this, we need to know if this span will be primary
725725
let is_primary = primary_path == Some(&origin.path);

src/renderer/styled_buffer.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,14 @@ impl StyledBuffer {
5151
let ch_style = style.color_spec(level, stylesheet);
5252
if ch_style != current_style {
5353
if !line.is_empty() {
54-
write!(str, "{}", current_style.render_reset())?;
54+
write!(str, "{current_style:#}")?;
5555
}
5656
current_style = ch_style;
57-
write!(str, "{}", current_style.render())?;
57+
write!(str, "{current_style}")?;
5858
}
5959
write!(str, "{ch}")?;
6060
}
61-
write!(str, "{}", current_style.render_reset())?;
61+
write!(str, "{current_style:#}")?;
6262
if i != self.lines.len() - 1 {
6363
writeln!(str)?;
6464
}

src/snippet.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ pub(crate) struct Id<'a> {
2222
/// A [diagnostic][crate::Renderer::render] is made of several `Group`s.
2323
/// `Group`s are used to [annotate][AnnotationKind::Primary] [`Snippet`]s
2424
/// with different [semantic reasons][Title].
25+
///
26+
/// # Example
27+
///
28+
/// ```rust
29+
#[doc = include_str!("../examples/highlight_message.rs")]
30+
/// ```
31+
#[doc = include_str!("../examples/highlight_message.svg")]
2532
#[derive(Clone, Debug)]
2633
pub struct Group<'a> {
2734
pub(crate) primary_level: Level<'a>,
@@ -36,6 +43,13 @@ impl<'a> Group<'a> {
3643
}
3744

3845
/// Create a title-less group with a primary [`Level`] for [`Annotation`]s
46+
///
47+
/// # Example
48+
///
49+
/// ```rust
50+
#[doc = include_str!("../examples/elide_header.rs")]
51+
/// ```
52+
#[doc = include_str!("../examples/elide_header.svg")]
3953
pub fn with_level(level: Level<'a>) -> Self {
4054
Self {
4155
primary_level: level,
@@ -386,9 +400,21 @@ impl<'a> Patch<'a> {
386400
}
387401
}
388402

389-
/// The referenced location (e.g. a path)
403+
/// A source location [`Element`] in a [`Group`]
390404
///
391405
/// If you have source available, see instead [`Snippet`]
406+
///
407+
/// # Example
408+
///
409+
/// ```rust
410+
/// # use annotate_snippets::{Group, Snippet, AnnotationKind, Level, Origin};
411+
/// let input = &[
412+
/// Group::with_title(Level::ERROR.title("mismatched types").id("E0308"))
413+
/// .element(
414+
/// Origin::path("$DIR/mismatched-types.rs")
415+
/// )
416+
/// ];
417+
/// ```
392418
#[derive(Clone, Debug)]
393419
pub struct Origin<'a> {
394420
pub(crate) path: Cow<'a, str>,
@@ -405,7 +431,7 @@ impl<'a> Origin<'a> {
405431
/// not allowed to be passed to this function.
406432
///
407433
/// </div>
408-
pub fn new(path: impl Into<Cow<'a, str>>) -> Self {
434+
pub fn path(path: impl Into<Cow<'a, str>>) -> Self {
409435
Self {
410436
path: path.into(),
411437
line: None,
@@ -441,7 +467,7 @@ impl<'a> Origin<'a> {
441467

442468
impl<'a> From<Cow<'a, str>> for Origin<'a> {
443469
fn from(origin: Cow<'a, str>) -> Self {
444-
Self::new(origin)
470+
Self::path(origin)
445471
}
446472
}
447473

tests/color/multiline_removal_suggestion.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ fn main() {}
8888
),
8989
Group::with_title(Level::NOTE.title("required by a bound in `flatten`"))
9090
.element(
91-
Origin::new("/rustc/FAKE_PREFIX/library/core/src/iter/traits/iterator.rs")
91+
Origin::path("/rustc/FAKE_PREFIX/library/core/src/iter/traits/iterator.rs")
9292
.line(1556)
9393
.char_column(4),
9494
),

tests/formatter.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2400,7 +2400,7 @@ fn secondary_title_no_level_text() {
24002400
.element(
24012401
Level::NOTE
24022402
.no_name()
2403-
.title("expected reference `&str`\nfound reference `&'static [u8; 0]`"),
2403+
.message("expected reference `&str`\nfound reference `&'static [u8; 0]`"),
24042404
),
24052405
];
24062406

@@ -2445,7 +2445,7 @@ fn secondary_title_custom_level_text() {
24452445
.element(
24462446
Level::NOTE
24472447
.with_name(Some("custom"))
2448-
.title("expected reference `&str`\nfound reference `&'static [u8; 0]`"),
2448+
.message("expected reference `&str`\nfound reference `&'static [u8; 0]`"),
24492449
),
24502450
];
24512451

tests/rustc_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1743,7 +1743,7 @@ fn main() {
17431743
Level::NOTE
17441744
.title("for a trait to be dyn compatible it needs to allow building a vtable\nfor more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>"))
17451745
.element(
1746-
Origin::new("$SRC_DIR/core/src/cmp.rs")
1746+
Origin::path("$SRC_DIR/core/src/cmp.rs")
17471747
.line(334)
17481748
.char_column(14)
17491749
.primary(true)

0 commit comments

Comments
 (0)