• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rust-lang / annotate-snippets-rs / 15600187927

12 Jun 2025 02:30AM UTC coverage: 86.521% (-0.8%) from 87.308%
15600187927

Pull #216

github

web-flow
Merge 47e7ec6a8 into ab692e676
Pull Request #216: fix: Match how rustc handles annotating newlines

2 of 2 new or added lines in 1 file covered. (100.0%)

15 existing lines in 1 file now uncovered.

1348 of 1558 relevant lines covered (86.52%)

4.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/src/renderer/styled_buffer.rs
1
//! Adapted from [styled_buffer]
2
//!
3
//! [styled_buffer]: https://github.com/rust-lang/rust/blob/894f7a4ba6554d3797404bbf550d9919df060b97/compiler/rustc_errors/src/styled_buffer.rs
4

5
use crate::renderer::stylesheet::Stylesheet;
6
use crate::renderer::ElementStyle;
7
use crate::Level;
8

9
use std::fmt;
10
use std::fmt::Write;
11

12
#[derive(Debug)]
13
pub(crate) struct StyledBuffer {
14
    lines: Vec<Vec<StyledChar>>,
15
}
16

17
#[derive(Clone, Copy, Debug, PartialEq)]
18
pub(crate) struct StyledChar {
19
    ch: char,
20
    style: ElementStyle,
21
}
22

23
impl StyledChar {
24
    pub(crate) const SPACE: Self = StyledChar::new(' ', ElementStyle::NoStyle);
25

26
    pub(crate) const fn new(ch: char, style: ElementStyle) -> StyledChar {
3✔
27
        StyledChar { ch, style }
28
    }
29
}
30

31
impl StyledBuffer {
32
    pub(crate) fn new() -> StyledBuffer {
9✔
33
        StyledBuffer { lines: vec![] }
11✔
34
    }
35

36
    fn ensure_lines(&mut self, line: usize) {
4✔
37
        if line >= self.lines.len() {
4✔
38
            self.lines.resize(line + 1, Vec::new());
4✔
39
        }
40
    }
41

42
    pub(crate) fn render(
4✔
43
        &self,
44
        level: Level<'_>,
45
        stylesheet: &Stylesheet,
46
        str: &mut String,
47
    ) -> Result<(), fmt::Error> {
48
        for (i, line) in self.lines.iter().enumerate() {
4✔
49
            let mut current_style = stylesheet.none;
4✔
50
            for StyledChar { ch, style } in line {
8✔
51
                let ch_style = style.color_spec(&level, stylesheet);
4✔
52
                if ch_style != current_style {
6✔
53
                    if !line.is_empty() {
2✔
54
                        write!(str, "{}", current_style.render_reset())?;
1✔
55
                    }
56
                    current_style = ch_style;
3✔
57
                    write!(str, "{}", current_style.render())?;
1✔
58
                }
59
                write!(str, "{ch}")?;
7✔
60
            }
61
            write!(str, "{}", current_style.render_reset())?;
8✔
62
            if i != self.lines.len() - 1 {
4✔
63
                writeln!(str)?;
8✔
64
            }
65
        }
66
        Ok(())
5✔
67
    }
68

69
    /// Sets `chr` with `style` for given `line`, `col`.
70
    /// If `line` does not exist in our buffer, adds empty lines up to the given
71
    /// and fills the last line with unstyled whitespace.
72
    pub(crate) fn putc(&mut self, line: usize, col: usize, chr: char, style: ElementStyle) {
4✔
73
        self.ensure_lines(line);
4✔
74
        if col >= self.lines[line].len() {
4✔
75
            self.lines[line].resize(col + 1, StyledChar::SPACE);
4✔
76
        }
77
        self.lines[line][col] = StyledChar::new(chr, style);
4✔
78
    }
79

80
    /// Sets `string` with `style` for given `line`, starting from `col`.
81
    /// If `line` does not exist in our buffer, adds empty lines up to the given
82
    /// and fills the last line with unstyled whitespace.
83
    pub(crate) fn puts(&mut self, line: usize, col: usize, string: &str, style: ElementStyle) {
4✔
84
        let mut n = col;
4✔
85
        for c in string.chars() {
9✔
86
            self.putc(line, n, c, style);
4✔
87
            n += 1;
8✔
88
        }
89
    }
90

91
    /// For given `line` inserts `string` with `style` after old content of that line,
92
    /// adding lines if needed
93
    pub(crate) fn append(&mut self, line: usize, string: &str, style: ElementStyle) {
4✔
94
        if line >= self.lines.len() {
4✔
95
            self.puts(line, 0, string, style);
4✔
96
        } else {
97
            let col = self.lines[line].len();
3✔
98
            self.puts(line, col, string, style);
4✔
99
        }
100
    }
101

102
    pub(crate) fn replace(&mut self, line: usize, start: usize, end: usize, string: &str) {
1✔
103
        if start == end {
1✔
104
            return;
105
        }
106
        let _ = self.lines[line].drain(start..(end - string.chars().count()));
4✔
107
        for (i, c) in string.chars().enumerate() {
6✔
108
            self.lines[line][start + i] = StyledChar::new(c, ElementStyle::LineNumber);
2✔
109
        }
110
    }
111

112
    /// For given `line` inserts `string` with `style` before old content of that line,
113
    /// adding lines if needed
114
    pub(crate) fn prepend(&mut self, line: usize, string: &str, style: ElementStyle) {
4✔
115
        self.ensure_lines(line);
6✔
116
        let string_len = string.chars().count();
4✔
117

118
        if !self.lines[line].is_empty() {
5✔
119
            // Push the old content over to make room for new content
120
            for _ in 0..string_len {
9✔
121
                self.lines[line].insert(0, StyledChar::SPACE);
5✔
122
            }
123
        }
124

125
        self.puts(line, 0, string, style);
5✔
126
    }
127

128
    pub(crate) fn num_lines(&self) -> usize {
4✔
129
        self.lines.len()
3✔
130
    }
131

132
    /// Set `style` for `line`, `col_start..col_end` range if:
133
    /// 1. That line and column range exist in `StyledBuffer`
134
    /// 2. `overwrite` is `true` or existing style is `Style::NoStyle` or `Style::Quotation`
135
    pub(crate) fn set_style_range(
3✔
136
        &mut self,
137
        line: usize,
138
        col_start: usize,
139
        col_end: usize,
140
        style: ElementStyle,
141
        overwrite: bool,
142
    ) {
143
        for col in col_start..col_end {
6✔
144
            self.set_style(line, col, style, overwrite);
3✔
145
        }
146
    }
147

148
    /// Set `style` for `line`, `col` if:
149
    /// 1. That line and column exist in `StyledBuffer`
150
    /// 2. `overwrite` is `true` or existing style is `Style::NoStyle` or `Style::Quotation`
151
    pub(crate) fn set_style(
3✔
152
        &mut self,
153
        line: usize,
154
        col: usize,
155
        style: ElementStyle,
156
        overwrite: bool,
157
    ) {
158
        if let Some(ref mut line) = self.lines.get_mut(line) {
3✔
159
            if let Some(StyledChar { style: s, .. }) = line.get_mut(col) {
5✔
160
                if overwrite || matches!(s, ElementStyle::NoStyle | ElementStyle::Quotation) {
4✔
161
                    *s = style;
2✔
162
                }
163
            }
164
        }
165
    }
166
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc