Skip to content

Commit 39672b2

Browse files
committed
fix!: Move Message contruction to Level
This fits with the session-type / type-state style builder and allows Diagnoatic adapters, like rustc, to leverage it vs the hard-coded functions.
1 parent b821bd3 commit 39672b2

21 files changed

+96
-103
lines changed

benches/simple.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ extern crate criterion;
44

55
use criterion::{black_box, Criterion};
66

7-
use annotate_snippets::{Label, Message, Renderer, Snippet};
7+
use annotate_snippets::{Label, Level, Renderer, Snippet};
88

99
fn create_snippet(renderer: Renderer) {
1010
let source = r#") -> Option<String> {
@@ -29,7 +29,7 @@ fn create_snippet(renderer: Renderer) {
2929
_ => continue,
3030
}
3131
}"#;
32-
let message = Message::error("mismatched types").id("E0308").snippet(
32+
let message = Level::Error.title("mismatched types").id("E0308").snippet(
3333
Snippet::new(source)
3434
.line_start(51)
3535
.origin("src/format.rs")

examples/expected_type.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
use annotate_snippets::{Label, Message, Renderer, Snippet};
1+
use annotate_snippets::{Label, Level, Renderer, Snippet};
22

33
fn main() {
44
let source = r#" annotations: vec![SourceAnnotation {
55
label: "expected struct `annotate_snippets::snippet::Slice`, found reference"
66
,
77
range: <22, 25>,"#;
8-
let message = Message::error("expected type, found `22`").snippet(
8+
let message = Level::Error.title("expected type, found `22`").snippet(
99
Snippet::new(source)
1010
.line_start(26)
1111
.origin("examples/footer.rs")

examples/footer.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
use annotate_snippets::{Label, Message, Renderer, Snippet};
1+
use annotate_snippets::{Label, Level, Renderer, Snippet};
22

33
fn main() {
4-
let message = Message::error("mismatched types")
4+
let message = Level::Error
5+
.title("mismatched types")
56
.id("E0308")
67
.snippet(
78
Snippet::new(" slices: vec![\"A\",")

examples/format.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use annotate_snippets::{Label, Message, Renderer, Snippet};
1+
use annotate_snippets::{Label, Level, Renderer, Snippet};
22

33
fn main() {
44
let source = r#") -> Option<String> {
@@ -23,7 +23,7 @@ fn main() {
2323
_ => continue,
2424
}
2525
}"#;
26-
let message = Message::error("mismatched types").id("E0308").snippet(
26+
let message = Level::Error.title("mismatched types").id("E0308").snippet(
2727
Snippet::new(source)
2828
.line_start(51)
2929
.origin("src/format.rs")

examples/multislice.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
use annotate_snippets::{Message, Renderer, Snippet};
1+
use annotate_snippets::{Level, Renderer, Snippet};
22

33
fn main() {
4-
let message = Message::error("mismatched types")
4+
let message = Level::Error
5+
.title("mismatched types")
56
.snippet(Snippet::new("Foo").line_start(51).origin("src/format.rs"))
67
.snippet(Snippet::new("Faa").line_start(129).origin("src/display.rs"));
78

src/renderer/display_list.rs

+21-11
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,9 @@ impl<'a> DisplayList<'a> {
107107

108108
pub(crate) fn new(
109109
snippet::Message {
110-
title,
110+
level,
111111
id,
112+
title,
112113
footer,
113114
snippets,
114115
}: snippet::Message<'a>,
@@ -118,7 +119,13 @@ impl<'a> DisplayList<'a> {
118119
) -> DisplayList<'a> {
119120
let mut body = vec![];
120121

121-
body.push(format_title(title, id));
122+
body.push(format_title(
123+
snippet::Label {
124+
level,
125+
label: title,
126+
},
127+
id,
128+
));
122129

123130
for (idx, snippet) in snippets.into_iter().enumerate() {
124131
body.append(&mut format_slice(
@@ -1206,7 +1213,7 @@ mod tests {
12061213

12071214
#[test]
12081215
fn test_format_title() {
1209-
let input = snippet::Message::error("This is a title").id("E0001");
1216+
let input = snippet::Level::Error.title("This is a title").id("E0001");
12101217
let output = from_display_lines(vec![DisplayLine::Raw(DisplayRawLine::Annotation {
12111218
annotation: Annotation {
12121219
annotation_type: DisplayAnnotationType::Error,
@@ -1227,8 +1234,9 @@ mod tests {
12271234
let line_1 = "This is line 1";
12281235
let line_2 = "This is line 2";
12291236
let source = [line_1, line_2].join("\n");
1230-
let input =
1231-
snippet::Message::error("").snippet(snippet::Snippet::new(&source).line_start(5402));
1237+
let input = snippet::Level::Error
1238+
.title("")
1239+
.snippet(snippet::Snippet::new(&source).line_start(5402));
12321240
let output = from_display_lines(vec![
12331241
DisplayLine::Raw(DisplayRawLine::Annotation {
12341242
annotation: Annotation {
@@ -1278,7 +1286,8 @@ mod tests {
12781286
let src_0_len = src_0.len();
12791287
let src_1 = "This is slice 2";
12801288
let src_1_len = src_1.len();
1281-
let input = snippet::Message::error("")
1289+
let input = snippet::Level::Error
1290+
.title("")
12821291
.snippet(
12831292
snippet::Snippet::new(src_0)
12841293
.line_start(5402)
@@ -1359,7 +1368,7 @@ mod tests {
13591368
let source = [line_1, line_2].join("\n");
13601369
// In line 2
13611370
let range = 22..24;
1362-
let input = snippet::Message::error("").snippet(
1371+
let input = snippet::Level::Error.title("").snippet(
13631372
snippet::Snippet::new(&source)
13641373
.line_start(5402)
13651374
.annotation(snippet::Label::info("Test annotation").span(range.clone())),
@@ -1429,8 +1438,9 @@ mod tests {
14291438

14301439
#[test]
14311440
fn test_format_label() {
1432-
let input =
1433-
snippet::Message::error("").footer(snippet::Label::error("This __is__ a title"));
1441+
let input = snippet::Level::Error
1442+
.title("")
1443+
.footer(snippet::Label::error("This __is__ a title"));
14341444
let output = from_display_lines(vec![
14351445
DisplayLine::Raw(DisplayRawLine::Annotation {
14361446
annotation: Annotation {
@@ -1465,7 +1475,7 @@ mod tests {
14651475
fn test_i26() {
14661476
let source = "short";
14671477
let label = "label";
1468-
let input = snippet::Message::error("").snippet(
1478+
let input = snippet::Level::Error.title("").snippet(
14691479
snippet::Snippet::new(source)
14701480
.line_start(0)
14711481
.annotation(snippet::Label::error(label).span(0..source.len() + 2)),
@@ -1475,7 +1485,7 @@ mod tests {
14751485

14761486
#[test]
14771487
fn test_i_29() {
1478-
let snippets = snippet::Message::error("oops").snippet(
1488+
let snippets = snippet::Level::Error.title("oops").snippet(
14791489
snippet::Snippet::new("First line\r\nSecond oops line")
14801490
.line_start(1)
14811491
.origin("<current file>")

src/renderer/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
//!
33
//! # Example
44
//! ```
5-
//! use annotate_snippets::{Renderer, Snippet, Message};
6-
//! let snippet = Message::error("mismatched types")
5+
//! use annotate_snippets::{Renderer, Snippet, Level};
6+
//! let snippet = Level::Error.title("mismatched types")
77
//! .snippet(Snippet::new("Foo").line_start(51).origin("src/format.rs"))
88
//! .snippet(Snippet::new("Faa").line_start(129).origin("src/display.rs"));
99
//!

src/snippet.rs

+17-31
Original file line numberDiff line numberDiff line change
@@ -5,51 +5,25 @@
55
//! ```
66
//! use annotate_snippets::*;
77
//!
8-
//! Message::error("mismatched types")
8+
//! Level::Error.title("mismatched types")
99
//! .snippet(Snippet::new("Foo").line_start(51).origin("src/format.rs"))
1010
//! .snippet(Snippet::new("Faa").line_start(129).origin("src/display.rs"));
1111
//! ```
1212
1313
use std::ops::Range;
1414

1515
/// Primary structure provided for formatting
16+
///
17+
/// See [`Level::title`] to create a [`Message`]
1618
pub struct Message<'a> {
17-
pub(crate) title: Label<'a>,
19+
pub(crate) level: Level,
1820
pub(crate) id: Option<&'a str>,
21+
pub(crate) title: &'a str,
1922
pub(crate) snippets: Vec<Snippet<'a>>,
2023
pub(crate) footer: Vec<Label<'a>>,
2124
}
2225

2326
impl<'a> Message<'a> {
24-
pub fn title(title: Label<'a>) -> Self {
25-
Self {
26-
title,
27-
id: None,
28-
snippets: vec![],
29-
footer: vec![],
30-
}
31-
}
32-
33-
pub fn error(title: &'a str) -> Self {
34-
Self::title(Label::error(title))
35-
}
36-
37-
pub fn warning(title: &'a str) -> Self {
38-
Self::title(Label::warning(title))
39-
}
40-
41-
pub fn info(title: &'a str) -> Self {
42-
Self::title(Label::info(title))
43-
}
44-
45-
pub fn note(title: &'a str) -> Self {
46-
Self::title(Label::note(title))
47-
}
48-
49-
pub fn help(title: &'a str) -> Self {
50-
Self::title(Label::help(title))
51-
}
52-
5327
pub fn id(mut self, id: &'a str) -> Self {
5428
self.id = Some(id);
5529
self
@@ -179,3 +153,15 @@ pub enum Level {
179153
Note,
180154
Help,
181155
}
156+
157+
impl Level {
158+
pub fn title(self, title: &str) -> Message<'_> {
159+
Message {
160+
level: self,
161+
id: None,
162+
title,
163+
snippets: vec![],
164+
footer: vec![],
165+
}
166+
}
167+
}

tests/fixtures/deserialize.rs

+5-17
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ pub struct Fixture<'a> {
1313

1414
#[derive(Deserialize)]
1515
pub struct MessageDef<'a> {
16-
#[serde(deserialize_with = "deserialize_label")]
16+
#[serde(with = "LevelDef")]
17+
pub level: Level,
1718
#[serde(borrow)]
18-
pub title: Label<'a>,
19+
pub title: &'a str,
1920
#[serde(default)]
2021
#[serde(borrow)]
2122
pub id: Option<&'a str>,
@@ -31,12 +32,13 @@ pub struct MessageDef<'a> {
3132
impl<'a> From<MessageDef<'a>> for Message<'a> {
3233
fn from(val: MessageDef<'a>) -> Self {
3334
let MessageDef {
35+
level,
3436
title,
3537
id,
3638
footer,
3739
snippets,
3840
} = val;
39-
let mut message = Message::title(title);
41+
let mut message = level.title(title);
4042
if let Some(id) = id {
4143
message = message.id(id);
4244
}
@@ -50,20 +52,6 @@ impl<'a> From<MessageDef<'a>> for Message<'a> {
5052
}
5153
}
5254

53-
fn deserialize_label<'de, D>(deserializer: D) -> Result<Label<'de>, D::Error>
54-
where
55-
D: Deserializer<'de>,
56-
{
57-
#[derive(Deserialize)]
58-
struct Wrapper<'a>(
59-
#[serde(with = "LabelDef")]
60-
#[serde(borrow)]
61-
LabelDef<'a>,
62-
);
63-
64-
Wrapper::deserialize(deserializer).map(|Wrapper(label)| Label::new(label.level, label.label))
65-
}
66-
6755
fn deserialize_labels<'de, D>(deserializer: D) -> Result<Vec<Label<'de>>, D::Error>
6856
where
6957
D: Deserializer<'de>,

tests/fixtures/no-color/issue_52.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
[message.title]
1+
[message]
22
level = "Error"
3-
label = ""
3+
title = ""
44

55
[[message.snippets]]
66
source = """

tests/fixtures/no-color/issue_9.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
[message.title]
2-
label = "expected one of `.`, `;`, `?`, or an operator, found `for`"
1+
[message]
32
level = "Error"
3+
title = "expected one of `.`, `;`, `?`, or an operator, found `for`"
44

55
[[message.snippets]]
66
source = "let x = vec![1];"

tests/fixtures/no-color/multiline_annotation.toml

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
[message]
2+
level = "Error"
3+
id = "E0308"
4+
title = "mismatched types"
5+
16
[[message.snippets]]
27
source = """
38
) -> Option<String> {
@@ -34,7 +39,3 @@ range = [5, 19]
3439
label = "expected enum `std::option::Option`, found ()"
3540
level = "Error"
3641
range = [22, 766]
37-
38-
[message]
39-
title = { level = "Error", label = "mismatched types" }
40-
id = "E0308"

tests/fixtures/no-color/multiline_annotation2.toml

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
[message]
2+
level = "Error"
3+
id = "E0027"
4+
title = "pattern does not mention fields `lineno`, `content`"
5+
16
[[message.snippets]]
27
source = """
38
if let DisplayLine::Source {
@@ -11,7 +16,3 @@ fold = false
1116
label = "missing fields `lineno`, `content`"
1217
level = "Error"
1318
range = [31, 128]
14-
15-
[message]
16-
title = { level = "Error", label = "pattern does not mention fields `lineno`, `content`" }
17-
id = "E0027"

tests/fixtures/no-color/multiline_annotation3.toml

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
[message]
2+
level = "Error"
3+
id = "E####"
4+
title = "spacing error found"
5+
16
[[message.snippets]]
27
source = """
38
This is an exampl
@@ -11,7 +16,3 @@ fold = false
1116
label = "this should not be on separate lines"
1217
level = "Error"
1318
range = [11, 18]
14-
15-
[message]
16-
title = { level = "Error", label = "spacing error found" }
17-
id = "E####"

tests/fixtures/no-color/multiple_annotations.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
[message.title]
1+
[message]
22
level = "Error"
3-
label = ""
3+
title = ""
44

55
[[message.snippets]]
66
source = """

tests/fixtures/no-color/one_past.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
[message.title]
2-
label = "expected `.`, `=`"
1+
[message]
32
level = "Error"
3+
title = "expected `.`, `=`"
44

55
[[message.snippets]]
66
source = "asdf"

tests/fixtures/no-color/simple.toml

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
[message]
2+
level = "Error"
3+
title = "expected one of `.`, `;`, `?`, or an operator, found `for`"
4+
15
[[message.snippets]]
26
source = """
37
})
@@ -13,6 +17,3 @@ range = [20, 23]
1317
label = "expected one of `.`, `;`, `?`, or an operator here"
1418
level = "Warning"
1519
range = [10, 11]
16-
[message.title]
17-
label = "expected one of `.`, `;`, `?`, or an operator, found `for`"
18-
level = "Error"

0 commit comments

Comments
 (0)