Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 40cec7a

Browse files
Merge pull request #30 from botika/master
Fix to no copy when format with yansi_term
2 parents 5cde073 + fc191d0 commit 40cec7a

File tree

6 files changed

+115
-87
lines changed

6 files changed

+115
-87
lines changed

‎Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ coveralls = { repository = "rust-lang/annotate-snippets-rs", branch = "master",
1616
maintenance = { status = "actively-developed" }
1717

1818
[dependencies]
19-
ansi_term = { version = "0.12", optional = true }
19+
yansi-term = { version = "0.1", optional = true }
2020

2121
[dev-dependencies]
2222
glob = "0.3"
2323
serde_yaml = "0.8"
2424
serde = { version = "1.0", features = ["derive"] }
2525
difference = "2.0"
26-
ansi_term = "0.12"
26+
yansi-term = "0.1"
2727
criterion = "0.3"
2828

2929
[[bench]]
@@ -32,4 +32,4 @@ harness = false
3232

3333
[features]
3434
default = []
35-
color = ["ansi_term"]
35+
color = ["yansi-term"]

‎src/formatter/mod.rs

Lines changed: 84 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use std::{
2-
cell::Cell,
32
cmp,
4-
fmt::{self, Display, Formatter,Write},
3+
fmt::{self, Display, Write},
54
};
65

76
pub mod style;
@@ -12,28 +11,6 @@ use self::style::{Style, StyleClass, Stylesheet};
1211
use crate::stylesheets::color::AnsiTermStylesheet;
1312
use crate::{display_list::*, stylesheets::no_color::NoColorStylesheet};
1413

15-
pub struct DisplayFn<F: FnOnce(&mut Formatter<'_>) -> fmt::Result>(std::cell::Cell<Option<F>>);
16-
17-
impl<F: FnOnce(&mut Formatter<'_>) -> fmt::Result> DisplayFn<F> {
18-
pub fn new(f: F) -> Self {
19-
Self(Cell::new(Some(f)))
20-
}
21-
}
22-
23-
impl<F: FnOnce(&mut Formatter<'_>) -> fmt::Result> Display for DisplayFn<F> {
24-
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
25-
self.0.take().ok_or(fmt::Error).and_then(|cl| cl(f))
26-
}
27-
}
28-
29-
fn repeat_char(c: char, n: usize) -> String {
30-
let mut s = String::with_capacity(c.len_utf8() * n);
31-
for _ in 0..n {
32-
s.push(c);
33-
}
34-
s
35-
}
36-
3714
fn format_repeat_char(c: char, n: usize, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3815
for _ in 0..n {
3916
f.write_char(c)?;
@@ -72,14 +49,18 @@ impl fmt::Display for DisplayList {
7249
lineno: Some(lineno),
7350
..
7451
} => {
75-
if self.anonymized_line_numbers {
76-
Self::ANONYMIZED_LINE_NUM.len()
77-
} else {
78-
cmp::max(lineno.to_string().len(), max)
79-
}
52+
// The largest line is the largest width.
53+
cmp::max(*lineno, max)
8054
}
8155
_ => max,
8256
});
57+
let lineno_width = if lineno_width == 0 {
58+
lineno_width
59+
} else if self.anonymized_line_numbers {
60+
Self::ANONYMIZED_LINE_NUM.len()
61+
} else {
62+
((lineno_width as f64).log10().floor() as usize) + 1
63+
};
8364
let inline_marks_width = self.body.iter().fold(0, |max, line| match line {
8465
DisplayLine::Source { inline_marks, .. } => cmp::max(inline_marks.len(), max),
8566
_ => max,
@@ -97,22 +78,38 @@ impl fmt::Display for DisplayList {
9778

9879
impl DisplayList {
9980
const ANONYMIZED_LINE_NUM: &'static str = "LL";
81+
const ERROR_TXT: &'static str = "error";
82+
const HELP_TXT: &'static str = "help";
83+
const INFO_TXT: &'static str = "info";
84+
const NOTE_TXT: &'static str = "note";
85+
const WARNING_TXT: &'static str = "warning";
10086

87+
#[inline]
10188
fn format_annotation_type(
102-
&self,
10389
annotation_type: &DisplayAnnotationType,
10490
f: &mut fmt::Formatter<'_>,
10591
) -> fmt::Result {
10692
match annotation_type {
107-
DisplayAnnotationType::Error => f.write_str("error"),
108-
DisplayAnnotationType::Warning => f.write_str("warning"),
109-
DisplayAnnotationType::Info => f.write_str("info"),
110-
DisplayAnnotationType::Note => f.write_str("note"),
111-
DisplayAnnotationType::Help => f.write_str("help"),
93+
DisplayAnnotationType::Error => f.write_str(Self::ERROR_TXT),
94+
DisplayAnnotationType::Help => f.write_str(Self::HELP_TXT),
95+
DisplayAnnotationType::Info => f.write_str(Self::INFO_TXT),
96+
DisplayAnnotationType::Note => f.write_str(Self::NOTE_TXT),
97+
DisplayAnnotationType::Warning => f.write_str(Self::WARNING_TXT),
11298
DisplayAnnotationType::None => Ok(()),
11399
}
114100
}
115101

102+
fn annotation_type_len(annotation_type: &DisplayAnnotationType) -> usize {
103+
match annotation_type {
104+
DisplayAnnotationType::Error => Self::ERROR_TXT.len(),
105+
DisplayAnnotationType::Help => Self::HELP_TXT.len(),
106+
DisplayAnnotationType::Info => Self::INFO_TXT.len(),
107+
DisplayAnnotationType::Note => Self::NOTE_TXT.len(),
108+
DisplayAnnotationType::Warning => Self::WARNING_TXT.len(),
109+
DisplayAnnotationType::None => 0,
110+
}
111+
}
112+
116113
fn get_annotation_style(&self, annotation_type: &DisplayAnnotationType) -> Box<dyn Style> {
117114
self.stylesheet.get_style(match annotation_type {
118115
DisplayAnnotationType::Error => StyleClass::Error,
@@ -148,37 +145,38 @@ impl DisplayList {
148145
f: &mut fmt::Formatter<'_>,
149146
) -> fmt::Result {
150147
let color = self.get_annotation_style(&annotation.annotation_type);
151-
152-
let formatted_type = if let Some(id) = &annotation.id {
153-
DisplayFn::new(|f| {
154-
self.format_annotation_type(&annotation.annotation_type, f)?;
155-
f.write_char('[')?;
156-
f.write_str(id)?;
157-
f.write_char(']')
158-
})
159-
.to_string()
148+
let formatted_len = if let Some(id) = &annotation.id {
149+
2 + id.len() + Self::annotation_type_len(&annotation.annotation_type)
160150
} else {
161-
DisplayFn::new(|f| self.format_annotation_type(&annotation.annotation_type, f))
162-
.to_string()
151+
Self::annotation_type_len(&annotation.annotation_type)
163152
};
164153

165154
if continuation {
166-
let indent = formatted_type.len() + 2;
167-
format_repeat_char(' ', indent, f)?;
155+
format_repeat_char(' ', formatted_len + 2, f)?;
168156
return self.format_label(&annotation.label, f);
169157
}
170-
if formatted_type.is_empty() {
158+
if formatted_len == 0 {
171159
self.format_label(&annotation.label, f)
172160
} else {
173-
color.paint(&formatted_type, f)?;
161+
color.paint_fn(
162+
Box::new(|f| {
163+
Self::format_annotation_type(&annotation.annotation_type, f)?;
164+
if let Some(id) = &annotation.id {
165+
f.write_char('[')?;
166+
f.write_str(id)?;
167+
f.write_char(']')?;
168+
}
169+
Ok(())
170+
}),
171+
f,
172+
)?;
174173
if !is_annotation_empty(annotation) {
175174
if in_source {
176-
color.paint(
177-
&DisplayFn::new(|f| {
175+
color.paint_fn(
176+
Box::new(|f| {
178177
f.write_str(": ")?;
179178
self.format_label(&annotation.label, f)
180-
})
181-
.to_string(),
179+
}),
182180
f,
183181
)?;
184182
} else {
@@ -230,21 +228,25 @@ impl DisplayList {
230228
_ => range.0,
231229
};
232230

233-
color.paint(&repeat_char(indent_char, indent_length + 1), f)?;
234-
color.paint(&repeat_char(mark, range.1 - indent_length), f)?;
231+
color.paint_fn(
232+
Box::new(|f| {
233+
format_repeat_char(indent_char, indent_length + 1, f)?;
234+
format_repeat_char(mark, range.1 - indent_length, f)
235+
}),
236+
f,
237+
)?;
235238

236239
if !is_annotation_empty(&annotation) {
237240
f.write_char(' ')?;
238-
color.paint(
239-
&DisplayFn::new(|f| {
241+
color.paint_fn(
242+
Box::new(|f| {
240243
self.format_annotation(
241244
annotation,
242245
annotation_part == &DisplayAnnotationPart::LabelContinuation,
243246
true,
244247
f,
245248
)
246-
})
247-
.to_string(),
249+
}),
248250
f,
249251
)?;
250252
}
@@ -254,14 +256,6 @@ impl DisplayList {
254256
}
255257
}
256258

257-
#[inline]
258-
fn format_lineno(&self, lineno: Option<usize>, lineno_width: usize) -> String {
259-
match lineno {
260-
Some(n) => format!("{:>width$}", n, width = lineno_width),
261-
None => repeat_char(' ', lineno_width),
262-
}
263-
}
264-
265259
#[inline]
266260
fn format_raw_line(
267261
&self,
@@ -337,10 +331,22 @@ impl DisplayList {
337331
} => {
338332
let lineno_color = self.stylesheet.get_style(StyleClass::LineNo);
339333
if self.anonymized_line_numbers && lineno.is_some() {
340-
lineno_color.paint(&format!("{} |", Self::ANONYMIZED_LINE_NUM), f)?;
334+
lineno_color.paint_fn(
335+
Box::new(|f| {
336+
f.write_str(Self::ANONYMIZED_LINE_NUM)?;
337+
f.write_str(" |")
338+
}),
339+
f,
340+
)?;
341341
} else {
342-
lineno_color.paint(
343-
&format!("{} |", self.format_lineno(*lineno, lineno_width)),
342+
lineno_color.paint_fn(
343+
Box::new(|f| {
344+
match lineno {
345+
Some(n) => write!(f, "{:>width$}", n, width = lineno_width),
346+
None => format_repeat_char(' ', lineno_width, f),
347+
}?;
348+
f.write_str(" |")
349+
}),
344350
f,
345351
)?;
346352
}
@@ -376,11 +382,13 @@ impl DisplayList {
376382
) -> fmt::Result {
377383
format_repeat_char(' ', inline_marks_width - inline_marks.len(), f)?;
378384
for mark in inline_marks {
379-
self.get_annotation_style(&mark.annotation_type).paint(
380-
match mark.mark_type {
381-
DisplayMarkType::AnnotationThrough => "|",
382-
DisplayMarkType::AnnotationStart => "/",
383-
},
385+
self.get_annotation_style(&mark.annotation_type).paint_fn(
386+
Box::new(|f| {
387+
f.write_char(match mark.mark_type {
388+
DisplayMarkType::AnnotationThrough => '|',
389+
DisplayMarkType::AnnotationStart => '/',
390+
})
391+
}),
384392
f,
385393
)?;
386394
}

‎src/formatter/style.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
//! Set of structures required to implement a stylesheet for
2-
//! [DisplayListFormatter](super::DisplayListFormatter).
1+
//! Set of structures required to implement a stylesheet
32
//!
43
//! In order to provide additional styling information for the
54
//! formatter, a structs can implement `Stylesheet` and `Style`
@@ -8,7 +7,6 @@
87
use std::fmt;
98

109
/// StyleClass is a collection of named variants of style classes
11-
/// that DisplayListFormatter uses.
1210
pub enum StyleClass {
1311
/// Message indicating an error.
1412
Error,
@@ -33,8 +31,14 @@ pub enum StyleClass {
3331

3432
/// This trait implements a return value for the `Stylesheet::get_style`.
3533
pub trait Style {
36-
/// The method used by the DisplayListFormatter to style the message.
34+
/// The method used to write text with formatter
3735
fn paint(&self, text: &str, f: &mut fmt::Formatter<'_>) -> fmt::Result;
36+
/// The method used to write display function with formatter
37+
fn paint_fn<'a>(
38+
&self,
39+
c: Box<dyn FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result + 'a>,
40+
f: &mut fmt::Formatter<'_>,
41+
) -> fmt::Result;
3842
/// The method used by the DisplayListFormatter to display the message
3943
/// in bold font.
4044
fn bold(&self) -> Box<dyn Style>;

‎src/stylesheets/color.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use std::fmt;
1+
use std::fmt::{self,Display};
22

3-
use ansi_term::{Color::Fixed, Style as AnsiTermStyle};
3+
use yansi_term::{Color::Fixed, Style as AnsiTermStyle};
44

55
use crate::formatter::style::{Style, StyleClass, Stylesheet};
66

@@ -10,7 +10,15 @@ struct AnsiTermStyleWrapper {
1010

1111
impl Style for AnsiTermStyleWrapper {
1212
fn paint(&self, text: &str, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13-
fmt::Display::fmt(&self.style.paint(text), f)
13+
self.style.paint(text).fmt(f)
14+
}
15+
16+
fn paint_fn<'a>(
17+
&self,
18+
c: Box<dyn FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result + 'a>,
19+
f: &mut fmt::Formatter<'_>,
20+
) -> fmt::Result {
21+
self.style.paint_fn(c).fmt(f)
1422
}
1523

1624
fn bold(&self) -> Box<dyn Style> {

‎src/stylesheets/no_color.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ impl Style for NoOpStyle {
99
f.write_str(text)
1010
}
1111

12+
fn paint_fn<'a>(
13+
&self,
14+
c: Box<dyn FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result + 'a>,
15+
f: &mut fmt::Formatter<'_>,
16+
) -> fmt::Result {
17+
c(f)
18+
}
19+
1220
fn bold(&self) -> Box<dyn Style> {
1321
Box::new(NoOpStyle {})
1422
}

‎tests/diff/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use ansi_term::Color::{Black, Green, Red};
21
use difference::{Changeset, Difference};
2+
use yansi_term::Color::{Black, Green, Red};
33

44
pub fn get_diff(left: &str, right: &str) -> String {
55
let mut output = String::new();

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /