Skip to content

Commit 4cbb80a

Browse files
committed
Add Snippet
1 parent 2d88713 commit 4cbb80a

File tree

9 files changed

+172
-72
lines changed

9 files changed

+172
-72
lines changed

benches/simple.rs

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ use criterion::Criterion;
66

77
use std::fmt::Write;
88

9-
use annotate_snippets::slice::{AnnotationType, SourceAnnotation};
10-
use annotate_snippets::{DisplayList, Slice};
9+
use annotate_snippets::{Annotation, AnnotationType, SourceAnnotation};
10+
use annotate_snippets::{Slice, Snippet};
11+
use annotate_snippets::DisplayList;
1112

1213
const SOURCE: &'static str = r#") -> Option<String> {
1314
for ann in annotations {
@@ -33,24 +34,32 @@ for ann in annotations {
3334
}"#;
3435

3536
fn create_snippet() {
36-
let slice = Slice {
37-
source: SOURCE,
38-
line_start: Some(51),
39-
origin: Some("src/format.rs"),
40-
annotations: vec![
41-
SourceAnnotation {
42-
label: "expected `Option<String>` because of return type",
43-
annotation_type: AnnotationType::Warning,
44-
range: (5, 19),
45-
},
46-
SourceAnnotation {
47-
label: "expected enum `std::option::Option`",
48-
annotation_type: AnnotationType::Error,
49-
range: (23, 725),
50-
},
51-
],
37+
let snippet = Snippet {
38+
title: Some(Annotation {
39+
id: Some("E0308"),
40+
label: Some("mismatched types"),
41+
annotation_type: AnnotationType::Error,
42+
}),
43+
footer: &[],
44+
slices: &[Slice {
45+
source: SOURCE,
46+
line_start: Some(51),
47+
origin: Some("src/format.rs"),
48+
annotations: vec![
49+
SourceAnnotation {
50+
label: "expected `Option<String>` because of return type",
51+
annotation_type: AnnotationType::Warning,
52+
range: (5, 19),
53+
},
54+
SourceAnnotation {
55+
label: "expected enum `std::option::Option`",
56+
annotation_type: AnnotationType::Error,
57+
range: (23, 725),
58+
},
59+
],
60+
}],
5261
};
53-
let dl: DisplayList = (&slice).into();
62+
let dl: DisplayList = (&snippet).into();
5463
let mut result = String::new();
5564
write!(result, "{}", dl).unwrap();
5665
}

examples/format.rs

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use annotate_snippets::slice::{AnnotationType, SourceAnnotation};
2-
use annotate_snippets::Slice;
1+
use annotate_snippets::{Annotation, AnnotationType, SourceAnnotation};
2+
use annotate_snippets::{Slice, Snippet};
33

44
fn main() {
55
let source = r#") -> Option<String> {
@@ -25,22 +25,30 @@ fn main() {
2525
}
2626
}"#;
2727

28-
let slice = Slice {
29-
source,
30-
line_start: Some(51),
31-
origin: Some("src/format.rs"),
32-
annotations: vec![
33-
SourceAnnotation {
34-
label: "expected `Option<String>` because of return type",
35-
annotation_type: AnnotationType::Warning,
36-
range: (5, 19),
37-
},
38-
SourceAnnotation {
39-
label: "expected enum `std::option::Option`",
40-
annotation_type: AnnotationType::Error,
41-
range: (23, 725),
42-
},
43-
],
28+
let snippet = Snippet {
29+
title: Some(Annotation {
30+
id: Some("E0308"),
31+
label: Some("mismatched types"),
32+
annotation_type: AnnotationType::Error,
33+
}),
34+
footer: &[],
35+
slices: &[Slice {
36+
source,
37+
line_start: Some(51),
38+
origin: Some("src/format.rs"),
39+
annotations: vec![
40+
SourceAnnotation {
41+
label: "expected `Option<String>` because of return type",
42+
annotation_type: AnnotationType::Warning,
43+
range: (5, 19),
44+
},
45+
SourceAnnotation {
46+
label: "expected enum `std::option::Option`",
47+
annotation_type: AnnotationType::Error,
48+
range: (23, 725),
49+
},
50+
],
51+
}],
4452
};
45-
println!("{}", slice);
53+
println!("{}", snippet);
4654
}

src/annotation.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#[derive(Debug, Clone)]
2+
pub struct Annotation<'s> {
3+
pub id: Option<&'s str>,
4+
pub label: Option<&'s str>,
5+
pub annotation_type: AnnotationType,
6+
}
7+
8+
#[derive(Debug, Clone)]
9+
pub enum AnnotationType {
10+
Error,
11+
Warning,
12+
Info,
13+
Note,
14+
Help,
15+
}
16+
17+
#[derive(Debug, Clone)]
18+
pub struct SourceAnnotation<'s> {
19+
pub range: (usize, usize),
20+
pub label: &'s str,
21+
pub annotation_type: AnnotationType,
22+
}

src/display_list/annotation.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use std::fmt;
22

33
#[derive(Debug, Clone)]
44
pub struct Annotation<'d> {
5+
pub annotation_type: DisplayAnnotationType,
6+
pub id: Option<&'d str>,
57
pub label: &'d str,
68
}
79

@@ -10,3 +12,26 @@ impl<'d> fmt::Display for Annotation<'d> {
1012
f.write_str(self.label)
1113
}
1214
}
15+
16+
#[derive(Debug, Clone)]
17+
pub enum DisplayAnnotationType {
18+
None,
19+
Error,
20+
Warning,
21+
Info,
22+
Note,
23+
Help,
24+
}
25+
26+
impl fmt::Display for DisplayAnnotationType {
27+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28+
match self {
29+
Self::None => Ok(()),
30+
Self::Error => f.write_str("error"),
31+
Self::Warning => f.write_str("warning"),
32+
Self::Info => f.write_str("info"),
33+
Self::Note => f.write_str("note"),
34+
Self::Help => f.write_str("help"),
35+
}
36+
}
37+
}

src/display_list/line.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::fmt;
2+
use std::fmt::Display;
23
use std::fmt::Write;
34

4-
use super::annotation::Annotation;
5+
use super::annotation::{Annotation, DisplayAnnotationType};
56

67
#[derive(Debug, Clone)]
78
pub enum DisplayLine<'d> {
@@ -88,6 +89,11 @@ pub enum DisplayRawLine<'d> {
8889
path: &'d str,
8990
pos: (Option<usize>, Option<usize>),
9091
},
92+
Annotation {
93+
annotation: Annotation<'d>,
94+
source_aligned: bool,
95+
continuation: bool,
96+
},
9197
}
9298

9399
impl<'d> DisplayRawLine<'d> {
@@ -101,6 +107,13 @@ impl<'d> DisplayRawLine<'d> {
101107
}
102108
f.write_char('\n')
103109
}
110+
Self::Annotation { annotation, .. } => {
111+
annotation.annotation_type.fmt(f)?;
112+
if let Some(id) = annotation.id {
113+
write!(f, "[{}]", id)?;
114+
}
115+
writeln!(f, ": {}", annotation.label)
116+
}
104117
}
105118
}
106119
}
@@ -125,13 +138,3 @@ pub enum DisplayMarkType {
125138
AnnotationThrough,
126139
AnnotationStart,
127140
}
128-
129-
#[derive(Debug, Clone)]
130-
pub enum DisplayAnnotationType {
131-
None,
132-
Error,
133-
Warning,
134-
Info,
135-
Note,
136-
Help,
137-
}

src/display_list/list.rs

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
use super::annotation::Annotation;
2-
use super::line::{
3-
DisplayAnnotationType, DisplayLine, DisplayMark, DisplayMarkType, DisplayRawLine,
4-
DisplaySourceLine,
5-
};
6-
use crate::slice::{Slice, SourceAnnotation};
1+
use super::annotation::{Annotation, DisplayAnnotationType};
2+
use super::line::{DisplayLine, DisplayMark, DisplayMarkType, DisplayRawLine, DisplaySourceLine};
3+
use crate::{Slice, Snippet, SourceAnnotation};
74
use std::cmp;
85
use std::fmt;
96

@@ -17,6 +14,31 @@ fn get_header_pos(slice: &Slice) -> (Option<usize>, Option<usize>) {
1714
(line, None)
1815
}
1916

17+
impl<'d> From<&Snippet<'d>> for DisplayList<'d> {
18+
fn from(snippet: &Snippet<'d>) -> Self {
19+
let mut body = vec![];
20+
21+
if let Some(annotation) = &snippet.title {
22+
let label = annotation.label.clone().unwrap_or_default();
23+
body.push(DisplayLine::Raw(DisplayRawLine::Annotation {
24+
annotation: Annotation {
25+
annotation_type: DisplayAnnotationType::Error,
26+
id: annotation.id,
27+
label: &label,
28+
},
29+
source_aligned: false,
30+
continuation: false,
31+
}));
32+
}
33+
34+
for slice in snippet.slices {
35+
let slice_dl: DisplayList = slice.into();
36+
body.extend(slice_dl.body);
37+
}
38+
DisplayList { body }
39+
}
40+
}
41+
2042
impl<'d> From<&Slice<'d>> for DisplayList<'d> {
2143
fn from(slice: &Slice<'d>) -> Self {
2244
let mut body = vec![];
@@ -107,7 +129,11 @@ impl<'d> From<&Slice<'d>> for DisplayList<'d> {
107129
lineno: None,
108130
inline_marks,
109131
line: DisplaySourceLine::Annotation {
110-
annotation: Annotation { label: ann.label },
132+
annotation: Annotation {
133+
annotation_type: DisplayAnnotationType::Error,
134+
id: None,
135+
label: ann.label,
136+
},
111137
range: (start, ann.range.1 - line_start_pos),
112138
},
113139
});

src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
pub mod annotation;
12
mod display_list;
23
pub mod slice;
4+
pub mod snippet;
35

6+
pub use annotation::{Annotation, AnnotationType, SourceAnnotation};
47
pub use display_list::DisplayList;
58
pub use slice::Slice;
9+
pub use snippet::Snippet;

src/slice.rs

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::annotation::SourceAnnotation;
12
use crate::display_list::DisplayList;
23
use std::fmt;
34

@@ -15,19 +16,3 @@ impl<'s> fmt::Display for Slice<'s> {
1516
write!(f, "{}", dl)
1617
}
1718
}
18-
19-
#[derive(Debug, Clone)]
20-
pub enum AnnotationType {
21-
Error,
22-
Warning,
23-
Info,
24-
Note,
25-
Help,
26-
}
27-
28-
#[derive(Debug, Clone)]
29-
pub struct SourceAnnotation<'s> {
30-
pub range: (usize, usize),
31-
pub label: &'s str,
32-
pub annotation_type: AnnotationType,
33-
}

src/snippet.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use crate::annotation::Annotation;
2+
use crate::display_list::DisplayList;
3+
use crate::slice::Slice;
4+
use std::fmt;
5+
6+
#[derive(Debug, Clone)]
7+
pub struct Snippet<'s> {
8+
pub title: Option<Annotation<'s>>,
9+
pub footer: &'s [Annotation<'s>],
10+
pub slices: &'s [Slice<'s>],
11+
}
12+
13+
impl<'s> fmt::Display for Snippet<'s> {
14+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15+
let dl: DisplayList = self.into();
16+
write!(f, "{}", dl)
17+
}
18+
}

0 commit comments

Comments
 (0)