Skip to content

Commit 3cf7ea1

Browse files
Muscraftepage
authored andcommitted
docs: Clarify meaning and use of API
1 parent 285b7ce commit 3cf7ea1

File tree

8 files changed

+409
-107
lines changed

8 files changed

+409
-107
lines changed

examples/expected_type.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ fn main() {
55
label: "expected struct `annotate_snippets::snippet::Slice`, found reference"
66
,
77
range: <22, 25>,"#;
8-
let message =
8+
let report =
99
&[
1010
Group::with_title(Level::ERROR.primary_title("expected type, found `22`")).element(
1111
Snippet::source(source)
@@ -23,5 +23,5 @@ fn main() {
2323
];
2424

2525
let renderer = Renderer::styled();
26-
anstream::println!("{}", renderer.render(message));
26+
anstream::println!("{}", renderer.render(report));
2727
}

examples/multi_suggestion.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use annotate_snippets::{
2+
renderer::DecorStyle, AnnotationKind, Group, Level, Patch, Renderer, Snippet,
3+
};
4+
5+
fn main() {
6+
let source = r#"
7+
#![allow(dead_code)]
8+
struct U <T> {
9+
wtf: Option<Box<U<T>>>,
10+
x: T,
11+
}
12+
fn main() {
13+
U {
14+
wtf: Some(Box(U {
15+
wtf: None,
16+
x: (),
17+
})),
18+
x: ()
19+
};
20+
let _ = std::collections::HashMap();
21+
let _ = std::collections::HashMap {};
22+
let _ = Box {};
23+
}
24+
"#;
25+
26+
let message = &[
27+
Group::with_title(Level::ERROR.primary_title(
28+
"cannot construct `Box<_, _>` with struct literal syntax due to private fields",
29+
))
30+
.element(
31+
Snippet::source(source)
32+
.path("$DIR/multi-suggestion.rs")
33+
.annotation(AnnotationKind::Primary.span(295..298)),
34+
)
35+
.element(Level::NOTE.message("private fields `0` and `1` that were not provided")),
36+
Group::with_title(Level::HELP.secondary_title(
37+
"you might have meant to use an associated function to build this type",
38+
))
39+
.element(
40+
Snippet::source(source)
41+
.path("$DIR/multi-suggestion.rs")
42+
.patch(Patch::new(298..301, "::new(_)")),
43+
)
44+
.element(
45+
Snippet::source(source)
46+
.path("$DIR/multi-suggestion.rs")
47+
.patch(Patch::new(298..301, "::new_uninit()")),
48+
)
49+
.element(
50+
Snippet::source(source)
51+
.path("$DIR/multi-suggestion.rs")
52+
.patch(Patch::new(298..301, "::new_zeroed()")),
53+
)
54+
.element(
55+
Snippet::source(source)
56+
.path("$DIR/multi-suggestion.rs")
57+
.patch(Patch::new(298..301, "::new_in(_, _)")),
58+
)
59+
.element(Level::NOTE.no_name().message("and 12 other candidates")),
60+
Group::with_title(Level::HELP.secondary_title("consider using the `Default` trait"))
61+
.element(
62+
Snippet::source(source)
63+
.path("$DIR/multi-suggestion.rs")
64+
.patch(Patch::new(295..295, "<"))
65+
.patch(Patch::new(
66+
298..301,
67+
" as std::default::Default>::default()",
68+
)),
69+
),
70+
];
71+
72+
let renderer = Renderer::styled().decor_style(DecorStyle::Unicode);
73+
anstream::println!("{}", renderer.render(message));
74+
}

examples/multi_suggestion.svg

Lines changed: 82 additions & 0 deletions
Loading

src/level.rs

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,23 @@ pub const HELP: Level<'_> = Level {
3737
};
3838

3939
/// Severity level for [`Title`]s and [`Message`]s
40+
///
41+
/// # Example
42+
///
43+
/// ```rust
44+
/// # use annotate_snippets::*;
45+
/// let report = &[
46+
/// Group::with_title(
47+
/// Level::ERROR.primary_title("mismatched types").id("E0308")
48+
/// )
49+
/// .element(
50+
/// Level::NOTE.message("expected reference"),
51+
/// ),
52+
/// Group::with_title(
53+
/// Level::HELP.secondary_title("function defined here")
54+
/// ),
55+
/// ];
56+
/// ```
4057
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
4158
pub struct Level<'a> {
4259
pub(crate) name: Option<Option<Cow<'a, str>>>,
@@ -53,9 +70,7 @@ impl<'a> Level<'a> {
5370
}
5471

5572
impl<'a> Level<'a> {
56-
/// Creates a [`Title`] that has bolded text, and is
57-
/// intended to be used with the "primary" (first)
58-
/// [`Group`][crate::Group] in a [`Report`][crate::Report].
73+
/// For the primary, or root cause, [`Group`][crate::Group] (the first) in a [`Report`][crate::Report]
5974
///
6075
/// See [`Group::with_title`][crate::Group::with_title]
6176
///
@@ -66,15 +81,6 @@ impl<'a> Level<'a> {
6681
/// not allowed to be passed to this function.
6782
///
6883
/// </div>
69-
///
70-
/// # Example
71-
///
72-
/// ```rust
73-
/// # use annotate_snippets::{Group, Snippet, AnnotationKind, Level};
74-
/// let input = &[
75-
/// Group::with_title(Level::ERROR.primary_title("mismatched types").id("E0308"))
76-
/// ];
77-
/// ```
7884
pub fn primary_title(self, text: impl Into<Cow<'a, str>>) -> Title<'a> {
7985
Title {
8086
level: self,
@@ -84,8 +90,7 @@ impl<'a> Level<'a> {
8490
}
8591
}
8692

87-
/// Creates a [`Title`] that is allowed to be styled, for more info see the
88-
/// warning below.
93+
/// For any secondary, or context, [`Group`][crate::Group]s (subsequent) in a [`Report`][crate::Report]
8994
///
9095
/// See [`Group::with_title`][crate::Group::with_title]
9196
///
@@ -116,20 +121,6 @@ impl<'a> Level<'a> {
116121
/// used to normalize untrusted text before it is passed to this function.
117122
///
118123
/// </div>
119-
///
120-
/// # Example
121-
///
122-
/// ```rust
123-
/// # use annotate_snippets::{Group, Snippet, AnnotationKind, Level};
124-
/// let input = &[
125-
/// Group::with_title(Level::ERROR.primary_title("mismatched types").id("E0308"))
126-
/// .element(
127-
/// Level::NOTE
128-
/// .no_name()
129-
/// .message("expected reference `&str`\nfound reference `&'static [u8; 0]`"),
130-
/// ),
131-
/// ];
132-
/// ```
133124
pub fn message(self, text: impl Into<Cow<'a, str>>) -> Message<'a> {
134125
Message {
135126
level: self,
@@ -182,6 +173,10 @@ impl<'a> Level<'a> {
182173

183174
/// Do not show the [`Level`]s name
184175
///
176+
/// Useful for:
177+
/// - Another layer of the application will include the level (e.g. when rendering errors)
178+
/// - [`Message`]s that are part of a previous [`Group`][crate::Group] [`Element`][crate::Element]s
179+
///
185180
/// # Example
186181
///
187182
/// ```rust
@@ -190,7 +185,7 @@ impl<'a> Level<'a> {
190185
/// let b: &[u8] = include_str!("file.txt"); //~ ERROR mismatched types
191186
/// let s: &str = include_bytes!("file.txt"); //~ ERROR mismatched types
192187
/// }"#;
193-
/// let input = &[
188+
/// let report = &[
194189
/// Group::with_title(Level::ERROR.primary_title("mismatched types").id("E0308"))
195190
/// .element(
196191
/// Snippet::source(source)

src/lib.rs

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
//! A library for formatting of text or programming code snippets.
2-
//!
3-
//! It's primary purpose is to build an ASCII-graphical representation of the snippet
4-
//! with annotations.
1+
//! Format [diagnostic reports][Report], including highlighting snippets of text
52
//!
63
//! # Example
74
//!
@@ -12,7 +9,83 @@
129
//!
1310
#![doc = include_str!("../examples/expected_type.svg")]
1411
//!
15-
//! # features
12+
//! # Visual overview
13+
//!
14+
//! [`Report`]
15+
//!
16+
#![doc = include_str!("../examples/multi_suggestion.svg")]
17+
//!
18+
//! ### Primary group
19+
//!
20+
//! [`Title`]
21+
//! ```text
22+
//! error: cannot construct `Box<_, _>` with struct literal syntax due to private fields
23+
//! ```
24+
//!
25+
//!
26+
//! [`Annotation`] on a [`Snippet`]
27+
//! ```text
28+
//! ╭▸ $DIR/multi-suggestion.rs:17:13
29+
//! │
30+
//! 17 │ let _ = Box {};
31+
//! │ ━━━
32+
//! │
33+
//! ```
34+
//!
35+
//! [`Message`]
36+
//! ```text
37+
//! ╰ note: private fields `0` and `1` that were not provided
38+
//! ```
39+
//!
40+
//!
41+
//!
42+
//! ### Secondary group: suggested fix
43+
//!
44+
//! [`Title`] (proposed solution)
45+
//! ```text
46+
//! help: you might have meant to use an associated function to build this type
47+
//! ```
48+
//!
49+
//! [`Patch`] Option 1 on a [`Snippet`]
50+
//! ```text
51+
//! ╭╴
52+
//! 21 - let _ = Box {};
53+
//! 21 + let _ = Box::new(_);
54+
//! ├╴
55+
//! ```
56+
//!
57+
//! [`Patch`] Option 2 on a [`Snippet`]
58+
//! ```text
59+
//! ├╴
60+
//! 17 - let _ = Box {};
61+
//! 17 + let _ = Box::new_uninit();
62+
//! ├╴
63+
//! ```
64+
//!
65+
//! *etc for Options 3 and 4*
66+
//!
67+
//! [`Message`]
68+
//! ```text
69+
//! ╰ and 12 other candidates
70+
//! ```
71+
//!
72+
//! ### Secondary group: alternative suggested fix
73+
//!
74+
//! [`Title`] (proposed solution)
75+
//! ```text
76+
//! help: consider using the `Default` trait
77+
//! ```
78+
//!
79+
//! Only [`Patch`] on a [`Snippet`]
80+
//! ```text
81+
//! ╭╴
82+
//! 17 - let _ = Box {};
83+
//! 17 + let _ = <Box as std::default::Default>::default();
84+
//! ╰╴
85+
//! ```
86+
//!
87+
//! # Cargo `features`
88+
//!
1689
//! - `testing-colors` - Makes [Renderer::styled] colors OS independent, which
1790
//! allows for easier testing when testing colored output. It should be added as
1891
//! a feature in `[dev-dependencies]`, which can be done with the following command:
@@ -30,6 +103,7 @@ pub mod renderer;
30103
mod snippet;
31104

32105
/// Normalize the string to avoid any unicode control characters.
106+
///
33107
/// This is important for untrusted input, as it can contain
34108
/// invalid unicode sequences.
35109
pub fn normalize_untrusted_str(s: &str) -> String {

0 commit comments

Comments
 (0)