Skip to content

Commit 997de0e

Browse files
committed
Fix no copy when cast Snippet to DisplayList
1 parent 40cec7a commit 997de0e

24 files changed

+414
-334
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ yansi-term = { version = "0.1", optional = true }
2020

2121
[dev-dependencies]
2222
glob = "0.3"
23-
serde_yaml = "0.8"
23+
toml = "0.5"
2424
serde = { version = "1.0", features = ["derive"] }
2525
difference = "2.0"
2626
yansi-term = "0.1"

benches/simple.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -34,26 +34,26 @@ fn create_snippet() {
3434
_ => continue,
3535
}
3636
}"#
37-
.to_string(),
37+
,
3838
line_start: 51,
39-
origin: Some("src/format.rs".to_string()),
39+
origin: Some("src/format.rs"),
4040
fold: false,
4141
annotations: vec![
4242
SourceAnnotation {
43-
label: "expected `Option<String>` because of return type".to_string(),
43+
label: "expected `Option<String>` because of return type",
4444
annotation_type: AnnotationType::Warning,
4545
range: (5, 19),
4646
},
4747
SourceAnnotation {
48-
label: "expected enum `std::option::Option`".to_string(),
48+
label: "expected enum `std::option::Option`",
4949
annotation_type: AnnotationType::Error,
5050
range: (26, 724),
5151
},
5252
],
5353
}],
5454
title: Some(Annotation {
55-
label: Some("mismatched types".to_string()),
56-
id: Some("E0308".to_string()),
55+
label: Some("mismatched types"),
56+
id: Some("E0308"),
5757
annotation_type: AnnotationType::Error,
5858
}),
5959
footer: vec![],

examples/expected_type.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,27 @@ use annotate_snippets::{
66
fn main() {
77
let snippet = Snippet {
88
title: Some(Annotation {
9-
label: Some("expected type, found `22`".to_string()),
9+
label: Some("expected type, found `22`"),
1010
id: None,
1111
annotation_type: AnnotationType::Error,
1212
}),
1313
footer: vec![],
1414
slices: vec![Slice {
1515
source: r#" annotations: vec![SourceAnnotation {
1616
label: "expected struct `annotate_snippets::snippet::Slice`, found reference"
17-
.to_string(),
18-
range: <22, 25>,"#
19-
.to_string(),
17+
,
18+
range: <22, 25>,"#,
2019
line_start: 26,
21-
origin: Some("examples/footer.rs".to_string()),
20+
origin: Some("examples/footer.rs"),
2221
fold: true,
2322
annotations: vec![
2423
SourceAnnotation {
25-
label: "".to_string(),
24+
label: "",
2625
annotation_type: AnnotationType::Error,
2726
range: (205, 207),
2827
},
2928
SourceAnnotation {
30-
label: "while parsing this struct".to_string(),
29+
label: "while parsing this struct",
3130
annotation_type: AnnotationType::Info,
3231
range: (34, 50),
3332
},

examples/footer.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,24 @@ use annotate_snippets::{
66
fn main() {
77
let snippet = Snippet {
88
title: Some(Annotation {
9-
label: Some("mismatched types".to_string()),
10-
id: Some("E0308".to_string()),
9+
label: Some("mismatched types"),
10+
id: Some("E0308"),
1111
annotation_type: AnnotationType::Error,
1212
}),
1313
footer: vec![Annotation {
1414
label: Some(
15-
"expected type: `snippet::Annotation`\n found type: `__&__snippet::Annotation`"
16-
.to_string(),
15+
"expected type: `snippet::Annotation`\n found type: `__&__snippet::Annotation`",
1716
),
1817
id: None,
1918
annotation_type: AnnotationType::Note,
2019
}],
2120
slices: vec![Slice {
22-
source: " slices: vec![\"A\",".to_string(),
21+
source: " slices: vec![\"A\",",
2322
line_start: 13,
24-
origin: Some("src/multislice.rs".to_string()),
23+
origin: Some("src/multislice.rs"),
2524
fold: false,
2625
annotations: vec![SourceAnnotation {
27-
label: "expected struct `annotate_snippets::snippet::Slice`, found reference"
28-
.to_string(),
26+
label: "expected struct `annotate_snippets::snippet::Slice`, found reference",
2927
range: (21, 24),
3028
annotation_type: AnnotationType::Error,
3129
}],

examples/format.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -27,27 +27,26 @@ fn main() {
2727
}
2828
_ => continue,
2929
}
30-
}"#
31-
.to_string(),
30+
}"#,
3231
line_start: 51,
33-
origin: Some("src/format.rs".to_string()),
32+
origin: Some("src/format.rs"),
3433
fold: false,
3534
annotations: vec![
3635
SourceAnnotation {
37-
label: "expected `Option<String>` because of return type".to_string(),
36+
label: "expected `Option<String>` because of return type",
3837
annotation_type: AnnotationType::Warning,
3938
range: (5, 19),
4039
},
4140
SourceAnnotation {
42-
label: "expected enum `std::option::Option`".to_string(),
41+
label: "expected enum `std::option::Option`",
4342
annotation_type: AnnotationType::Error,
4443
range: (26, 724),
4544
},
4645
],
4746
}],
4847
title: Some(Annotation {
49-
label: Some("mismatched types".to_string()),
50-
id: Some("E0308".to_string()),
48+
label: Some("mismatched types"),
49+
id: Some("E0308"),
5150
annotation_type: AnnotationType::Error,
5251
}),
5352
footer: vec![],

examples/multislice.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,23 @@ use annotate_snippets::{
66
fn main() {
77
let snippet = Snippet {
88
title: Some(Annotation {
9-
label: Some("mismatched types".to_string()),
9+
label: Some("mismatched types"),
1010
id: None,
1111
annotation_type: AnnotationType::Error,
1212
}),
1313
footer: vec![],
1414
slices: vec![
1515
Slice {
16-
source: "Foo".to_string(),
16+
source: "Foo",
1717
line_start: 51,
18-
origin: Some("src/format.rs".to_string()),
18+
origin: Some("src/format.rs"),
1919
fold: false,
2020
annotations: vec![],
2121
},
2222
Slice {
23-
source: "Faa".to_string(),
23+
source: "Faa",
2424
line_start: 129,
25-
origin: Some("src/display.rs".to_string()),
25+
origin: Some("src/display.rs"),
2626
fold: false,
2727
annotations: vec![],
2828
},

src/display_list/from_snippet.rs

+73-34
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
use super::*;
33
use crate::{formatter::get_term_style, snippet};
44

5-
fn format_label(label: Option<&str>, style: Option<DisplayTextStyle>) -> Vec<DisplayTextFragment> {
5+
fn format_label(
6+
label: Option<&str>,
7+
style: Option<DisplayTextStyle>,
8+
) -> Vec<DisplayTextFragment<'_>> {
69
let mut result = vec![];
710
if let Some(label) = label {
811
for (idx, element) in label.split("__").enumerate() {
@@ -17,15 +20,15 @@ fn format_label(label: Option<&str>, style: Option<DisplayTextStyle>) -> Vec<Dis
1720
}
1821
};
1922
result.push(DisplayTextFragment {
20-
content: element.to_string(),
23+
content: element,
2124
style: element_style,
2225
});
2326
}
2427
}
2528
result
2629
}
2730

28-
fn format_title(annotation: snippet::Annotation) -> DisplayLine {
31+
fn format_title(annotation: snippet::Annotation<'_>) -> DisplayLine<'_> {
2932
let label = annotation.label.unwrap_or_default();
3033
DisplayLine::Raw(DisplayRawLine::Annotation {
3134
annotation: Annotation {
@@ -38,7 +41,7 @@ fn format_title(annotation: snippet::Annotation) -> DisplayLine {
3841
})
3942
}
4043

41-
fn format_annotation(annotation: snippet::Annotation) -> Vec<DisplayLine> {
44+
fn format_annotation(annotation: snippet::Annotation<'_>) -> Vec<DisplayLine<'_>> {
4245
let mut result = vec![];
4346
let label = annotation.label.unwrap_or_default();
4447
for (i, line) in label.lines().enumerate() {
@@ -55,7 +58,11 @@ fn format_annotation(annotation: snippet::Annotation) -> Vec<DisplayLine> {
5558
result
5659
}
5760

58-
fn format_slice(mut slice: snippet::Slice, is_first: bool, has_footer: bool) -> Vec<DisplayLine> {
61+
fn format_slice(
62+
mut slice: snippet::Slice<'_>,
63+
is_first: bool,
64+
has_footer: bool,
65+
) -> Vec<DisplayLine<'_>> {
5966
let main_range = slice.annotations.get(0).map(|x| x.range.0);
6067
let row = slice.line_start;
6168
let origin = slice.origin.take();
@@ -70,13 +77,13 @@ fn format_slice(mut slice: snippet::Slice, is_first: bool, has_footer: bool) ->
7077
result
7178
}
7279

73-
fn format_header(
74-
origin: Option<String>,
80+
fn format_header<'a>(
81+
origin: Option<&'a str>,
7582
main_range: Option<usize>,
7683
mut row: usize,
77-
body: &[DisplayLine],
84+
body: &[DisplayLine<'_>],
7885
is_first: bool,
79-
) -> Option<DisplayLine> {
86+
) -> Option<DisplayLine<'a>> {
8087
let display_header = if is_first {
8188
DisplayHeaderType::Initial
8289
} else {
@@ -117,17 +124,19 @@ fn format_header(
117124
None
118125
}
119126

120-
fn fold_body(body: &[DisplayLine]) -> Vec<DisplayLine> {
121-
let mut new_body = vec![];
127+
fn fold_body(mut body: Vec<DisplayLine<'_>>) -> Vec<DisplayLine<'_>> {
128+
enum Line {
129+
Fold(usize),
130+
Source(usize),
131+
};
122132

133+
let mut lines = vec![];
123134
let mut no_annotation_lines_counter = 0;
124-
let mut idx = 0;
125135

126-
while idx < body.len() {
127-
match body[idx] {
136+
for (idx, line) in body.iter().enumerate() {
137+
match line {
128138
DisplayLine::Source {
129139
line: DisplaySourceLine::Annotation { .. },
130-
ref inline_marks,
131140
..
132141
} => {
133142
if no_annotation_lines_counter > 2 {
@@ -143,40 +152,71 @@ fn fold_body(body: &[DisplayLine]) -> Vec<DisplayLine> {
143152
} else {
144153
1
145154
};
146-
for item in body.iter().take(fold_start + pre_len).skip(fold_start) {
147-
new_body.push(item.clone());
155+
for (i, _) in body
156+
.iter()
157+
.enumerate()
158+
.take(fold_start + pre_len)
159+
.skip(fold_start)
160+
{
161+
lines.push(Line::Source(i));
148162
}
149-
new_body.push(DisplayLine::Fold {
150-
inline_marks: inline_marks.clone(),
151-
});
152-
for item in body.iter().take(fold_end).skip(fold_end - post_len) {
153-
new_body.push(item.clone());
163+
lines.push(Line::Fold(idx));
164+
for (i, _) in body
165+
.iter()
166+
.enumerate()
167+
.take(fold_end)
168+
.skip(fold_end - post_len)
169+
{
170+
lines.push(Line::Source(i));
154171
}
155172
} else {
156173
let start = idx - no_annotation_lines_counter;
157-
for item in body.iter().take(idx).skip(start) {
158-
new_body.push(item.clone());
174+
for (i, _) in body.iter().enumerate().take(idx).skip(start) {
175+
lines.push(Line::Source(i));
159176
}
160177
}
161178
no_annotation_lines_counter = 0;
162179
}
163180
DisplayLine::Source { .. } => {
164181
no_annotation_lines_counter += 1;
165-
idx += 1;
166182
continue;
167183
}
168184
_ => {
169185
no_annotation_lines_counter += 1;
170186
}
171187
}
172-
new_body.push(body[idx].clone());
173-
idx += 1;
188+
lines.push(Line::Source(idx));
189+
}
190+
191+
let mut new_body = vec![];
192+
let mut removed = 0;
193+
for line in lines {
194+
match line {
195+
Line::Source(i) => {
196+
new_body.push(body.remove(i - removed));
197+
removed += 1;
198+
}
199+
Line::Fold(i) => {
200+
if let DisplayLine::Source {
201+
line: DisplaySourceLine::Annotation { .. },
202+
ref inline_marks,
203+
..
204+
} = body.get(i - removed).unwrap()
205+
{
206+
new_body.push(DisplayLine::Fold {
207+
inline_marks: inline_marks.clone(),
208+
})
209+
} else {
210+
unreachable!()
211+
}
212+
}
213+
}
174214
}
175215

176216
new_body
177217
}
178218

179-
fn format_body(slice: snippet::Slice, has_footer: bool) -> Vec<DisplayLine> {
219+
fn format_body(slice: snippet::Slice<'_>, has_footer: bool) -> Vec<DisplayLine<'_>> {
180220
let source_len = slice.source.chars().count();
181221
if let Some(bigger) = slice.annotations.iter().find_map(|x| {
182222
if source_len < x.range.1 {
@@ -205,7 +245,7 @@ fn format_body(slice: snippet::Slice, has_footer: bool) -> Vec<DisplayLine> {
205245
lineno: Some(current_line),
206246
inline_marks: vec![],
207247
line: DisplaySourceLine::Content {
208-
text: line.to_string(),
248+
text: line,
209249
range: line_range,
210250
},
211251
});
@@ -361,7 +401,7 @@ fn format_body(slice: snippet::Slice, has_footer: bool) -> Vec<DisplayLine> {
361401
}
362402

363403
if slice.fold {
364-
body = fold_body(&body);
404+
body = fold_body(body);
365405
}
366406

367407
body.insert(
@@ -388,16 +428,15 @@ fn format_body(slice: snippet::Slice, has_footer: bool) -> Vec<DisplayLine> {
388428
body
389429
}
390430

391-
// TODO: From reference to DisplayList<'a>
392-
impl From<snippet::Snippet> for DisplayList {
431+
impl<'a> From<snippet::Snippet<'a>> for DisplayList<'a> {
393432
fn from(
394433
snippet::Snippet {
395434
title,
396435
footer,
397436
slices,
398437
opt,
399-
}: snippet::Snippet,
400-
) -> Self {
438+
}: snippet::Snippet<'a>,
439+
) -> DisplayList<'a> {
401440
let mut body = vec![];
402441
if let Some(annotation) = title {
403442
body.push(format_title(annotation));

0 commit comments

Comments
 (0)