Skip to content

Fix double chars #205

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/renderer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2048,7 +2048,6 @@ impl Renderer {
})
.collect();

buffer.puts(line_offset, code_offset, &code, ElementStyle::Quotation);
let placeholder = self.margin();
let padding = str_width(placeholder);
let (width_taken, bytes_taken) = if margin.was_cut_left() {
Expand Down
12 changes: 6 additions & 6 deletions src/snippet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub(crate) const NOTE_TXT: &str = "note";
pub(crate) const WARNING_TXT: &str = "warning";

/// Top-level user message
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct Message<'a> {
pub(crate) id: Option<&'a str>, // for "correctness", could be sloppy and be on Title
pub(crate) groups: Vec<Group<'a>>,
Expand Down Expand Up @@ -76,7 +76,7 @@ impl<'a> Message<'a> {
}

/// An [`Element`] container
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct Group<'a> {
pub(crate) elements: Vec<Element<'a>>,
}
Expand Down Expand Up @@ -108,7 +108,7 @@ impl<'a> Group<'a> {
}

/// A section of content within a [`Group`]
#[derive(Debug)]
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum Element<'a> {
Title(Title<'a>),
Expand Down Expand Up @@ -149,13 +149,13 @@ impl From<Padding> for Element<'_> {
}

/// A whitespace [`Element`] in a [`Group`]
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct Padding;

/// A text [`Element`] in a [`Group`]
///
/// See [`Level::title`] to create this.
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct Title<'a> {
pub(crate) level: Level<'a>,
pub(crate) title: &'a str,
Expand All @@ -170,7 +170,7 @@ impl Title<'_> {
}

/// A source view [`Element`] in a [`Group`]
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct Snippet<'a, T> {
pub(crate) origin: Option<&'a str>,
pub(crate) line_start: usize,
Expand Down
137 changes: 114 additions & 23 deletions tests/formatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2129,7 +2129,7 @@ fn unicode_cut_handling() {
.annotation(AnnotationKind::Primary.span(85..228).label("annotation")),
),
);
let expected = str![[r#"
let expected_ascii = str![[r#"
error: title
|
1 | version = "0.1.0"
Expand All @@ -2140,8 +2140,22 @@ error: title
5 | | ]
| |_^ annotation
"#]];
let renderer = Renderer::plain();
assert_data_eq!(renderer.render(input), expected);
let renderer_ascii = Renderer::plain();
assert_data_eq!(renderer_ascii.render(input.clone()), expected_ascii);

let expected_unicode = str![[r#"
error: title
1 │ version = "0.1.0"
2 │ # Ensure that the spans from toml handle utf-8 correctly
3 │ authors = [
│ ┏━━━━━━━━━━━┛
4 │ ┃ { name = "Z͑ͫ̓ͪ̂ͫ̽͏̴̙̤̞͉͚̯̞̠͍A̴̵̜̰͔ͫ͗͢L̠ͨͧͩ͘G̴̻͈͍͔̹̑͗̎̅͛́Ǫ̵̹̻̝̳͂̌̌͘", email = 1 }
5 │ ┃ ]
╰╴┗━┛ annotation
"#]];
let renderer_unicode = renderer_ascii.theme(OutputTheme::Unicode);
assert_data_eq!(renderer_unicode.render(input), expected_unicode);
}

#[test]
Expand All @@ -2159,16 +2173,26 @@ fn unicode_cut_handling2() {
)
);

let expected = str![[r#"
let expected_ascii = str![[r#"
error: expected item, found `?`
|
1 | ...的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。*/?
| ^ expected item
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
"#]];

let renderer = Renderer::plain();
assert_data_eq!(renderer.render(input), expected);
let renderer_ascii = Renderer::plain();
assert_data_eq!(renderer_ascii.render(input.clone()), expected_ascii);

let expected_unicode = str![[r#"
error: expected item, found `?`
1 │ …宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。*/?
│ ━ expected item
╰ note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
"#]];
let renderer_unicode = renderer_ascii.theme(OutputTheme::Unicode);
assert_data_eq!(renderer_unicode.render(input), expected_unicode);
}

#[test]
Expand All @@ -2186,16 +2210,26 @@ fn unicode_cut_handling3() {
)
);

let expected = str![[r#"
let expected_ascii = str![[r#"
error: expected item, found `?`
|
1 | ...。这是宽的。这是宽的。这是宽的...
| ^^ expected item
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
"#]];

let renderer = Renderer::plain().term_width(43);
assert_data_eq!(renderer.render(input), expected);
let renderer_ascii = Renderer::plain().term_width(43);
assert_data_eq!(renderer_ascii.render(input.clone()), expected_ascii);

let expected_unicode = str![[r#"
error: expected item, found `?`
1 │ …的。这是宽的。这是宽的。这是宽的。…
│ ━━ expected item
╰ note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
"#]];
let renderer_unicode = renderer_ascii.theme(OutputTheme::Unicode);
assert_data_eq!(renderer_unicode.render(input), expected_unicode);
}

#[test]
Expand All @@ -2213,16 +2247,26 @@ fn unicode_cut_handling4() {
)
);

let expected = str![[r#"
let expected_ascii = str![[r#"
error: expected item, found `?`
|
1 | ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/?
| ^ expected item
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
"#]];

let renderer = Renderer::plain();
assert_data_eq!(renderer.render(input), expected);
let renderer_ascii = Renderer::plain();
assert_data_eq!(renderer_ascii.render(input.clone()), expected_ascii);

let expected_unicode = str![[r#"
error: expected item, found `?`
1 │ …aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/?
│ ━ expected item
╰ note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
"#]];
let renderer_unicode = renderer_ascii.theme(OutputTheme::Unicode);
assert_data_eq!(renderer_unicode.render(input), expected_unicode);
}

#[test]
Expand Down Expand Up @@ -2252,7 +2296,7 @@ fn main() {
),
);

let expected = str![[r#"
let expected_ascii = str![[r#"
error[E0308]: mismatched types
--> $DIR/non-whitespace-trimming-unicode.rs:4:415
|
Expand All @@ -2262,8 +2306,20 @@ LL | ...♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾
| expected due to this
"#]];

let renderer = Renderer::plain().anonymized_line_numbers(true);
assert_data_eq!(renderer.render(input), expected);
let renderer_ascii = Renderer::plain().anonymized_line_numbers(true);
assert_data_eq!(renderer_ascii.render(input.clone()), expected_ascii);

let expected_unicode = str![[r#"
error[E0308]: mismatched types
╭▸ $DIR/non-whitespace-trimming-unicode.rs:4:415
LL │ …♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4"; let _: () = 42; let _: &str = "🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓ ☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹…
│ ┬─ ━━ expected `()`, found integer
│ │
╰╴ expected due to this
"#]];
let renderer_unicode = renderer_ascii.theme(OutputTheme::Unicode);
assert_data_eq!(renderer_unicode.render(input), expected_unicode);
}

#[test]
Expand Down Expand Up @@ -2311,7 +2367,27 @@ fn main() {
),
);

let expected = str![[r#"
let expected_ascii = str![[r#"
error[E0369]: cannot add `&str` to `&str`
--> $DIR/non-1-width-unicode-multiline-label.rs:7:260
|
LL | ...࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!";
| -------------- ^ -------------- &str
| | |
| | `+` cannot be used to concatenate two `&str` strings
| &str
|
= note: string concatenation requires an owned `String` on the left
help: create an owned `String` from a string reference
|
LL | let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇ཈ཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬ཭཮཯཰ཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun.to_owned() + " really fun!";
| +++++++++++
"#]];

let renderer_ascii = Renderer::plain().anonymized_line_numbers(true);
assert_data_eq!(renderer_ascii.render(input.clone()), expected_ascii);

let expected_unicode = str![[r#"
error[E0369]: cannot add `&str` to `&str`
╭▸ $DIR/non-1-width-unicode-multiline-label.rs:7:260
Expand All @@ -2328,10 +2404,8 @@ LL │ let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓
╰╴ +++++++++++
"#]];

let renderer = Renderer::plain()
.anonymized_line_numbers(true)
.theme(OutputTheme::Unicode);
assert_data_eq!(renderer.render(input), expected);
let renderer_unicode = renderer_ascii.theme(OutputTheme::Unicode);
assert_data_eq!(renderer_unicode.render(input), expected_unicode);
}

#[test]
Expand Down Expand Up @@ -2367,7 +2441,7 @@ fn foo() {
.element(Level::NOTE.title("this error originates in the macro `include` (in Nightly builds, run with -Z macro-backtrace for more info)")),
);

let expected = str![[r#"
let expected_ascii = str![[r#"
error: couldn't read `$DIR/not-utf8.bin`: stream did not contain valid UTF-8
--> $DIR/not-utf8.rs:6:5
|
Expand All @@ -2382,6 +2456,23 @@ LL | �|�␂!5�cc␕␂�Ӻi��WWj�ȥ�'�}�␒�J�ȉ��W
= note: this error originates in the macro `include` (in Nightly builds, run with -Z macro-backtrace for more info)
"#]];

let renderer = Renderer::plain().anonymized_line_numbers(true);
assert_data_eq!(renderer.render(input), expected);
let renderer_ascii = Renderer::plain().anonymized_line_numbers(true);
assert_data_eq!(renderer_ascii.render(input.clone()), expected_ascii);

let expected_unicode = str![[r#"
error: couldn't read `$DIR/not-utf8.bin`: stream did not contain valid UTF-8
╭▸ $DIR/not-utf8.rs:6:5
LL │ include!("not-utf8.bin");
│ ━━━━━━━━━━━━━━━━━━━━━━━━
╰╴
note: byte `193` is not valid utf-8
╭▸ $DIR/not-utf8.bin:1:1
LL │ �|�␂!5�cc␕␂�Ӻi��WWj�ȥ�'�}�␒�J�ȉ��W�␞O�@����␜w�V���LO����␔[ ␃_�'���SQ�~ذ��ų&��- ��lN~��!@␌ _#���kQ��h�␝�:�␜␇�
│ ━
╰ note: this error originates in the macro `include` (in Nightly builds, run with -Z macro-backtrace for more info)
"#]];
let renderer_unicode = renderer_ascii.theme(OutputTheme::Unicode);
assert_data_eq!(renderer_unicode.render(input), expected_unicode);
}