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

rust-lang / annotate-snippets-rs / 16010663667

01 Jul 2025 09:35PM UTC coverage: 87.43% (+0.3%) from 87.105%
16010663667

Pull #237

github

web-flow
Merge 49322a759 into 74c251759
Pull Request #237: fix: Force group levels to be explicitly given

5 of 5 new or added lines in 2 files covered. (100.0%)

2 existing lines in 1 file now uncovered.

1405 of 1607 relevant lines covered (87.43%)

4.93 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 {
5✔
33
        StyledBuffer { lines: vec![] }
7✔
34
    }
35

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

42
    pub(crate) fn render(
5✔
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() {
10✔
49
            let mut current_style = stylesheet.none;
4✔
50
            for StyledChar { ch, style } in line {
10✔
51
                let ch_style = style.color_spec(level, stylesheet);
6✔
52
                if ch_style != current_style {
5✔
53
                    if !line.is_empty() {
1✔
54
                        write!(str, "{}", current_style.render_reset())?;
3✔
55
                    }
56
                    current_style = ch_style;
1✔
57
                    write!(str, "{}", current_style.render())?;
3✔
58
                }
59
                write!(str, "{ch}")?;
5✔
60
            }
61
            write!(str, "{}", current_style.render_reset())?;
5✔
62
            if i != self.lines.len() - 1 {
5✔
63
                writeln!(str)?;
5✔
64
            }
65
        }
66
        Ok(())
8✔
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) {
3✔
73
        self.ensure_lines(line);
3✔
74
        if col >= self.lines[line].len() {
3✔
75
            self.lines[line].resize(col + 1, StyledChar::SPACE);
3✔
76
        }
77
        self.lines[line][col] = StyledChar::new(chr, style);
3✔
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) {
3✔
84
        let mut n = col;
3✔
85
        for c in string.chars() {
7✔
86
            self.putc(line, n, c, style);
3✔
87
            n += 1;
7✔
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) {
3✔
94
        if line >= self.lines.len() {
4✔
95
            self.puts(line, 0, string, style);
3✔
96
        } else {
97
            let col = self.lines[line].len();
3✔
98
            self.puts(line, col, string, style);
3✔
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
        // If the replacement range would be out of bounds, do nothing, as we
107
        // can't replace things that don't exist.
108
        if start > self.lines[line].len() || end > self.lines[line].len() {
2✔
109
            return;
110
        }
111
        let _ = self.lines[line].drain(start..(end - string.chars().count()));
1✔
112
        for (i, c) in string.chars().enumerate() {
3✔
113
            self.lines[line][start + i] = StyledChar::new(c, ElementStyle::LineNumber);
1✔
114
        }
115
    }
116

117
    /// For given `line` inserts `string` with `style` before old content of that line,
118
    /// adding lines if needed
119
    pub(crate) fn prepend(&mut self, line: usize, string: &str, style: ElementStyle) {
5✔
120
        self.ensure_lines(line);
3✔
121
        let string_len = string.chars().count();
5✔
122

123
        if !self.lines[line].is_empty() {
3✔
124
            // Push the old content over to make room for new content
125
            for _ in 0..string_len {
12✔
126
                self.lines[line].insert(0, StyledChar::SPACE);
6✔
127
            }
128
        }
129

130
        self.puts(line, 0, string, style);
5✔
131
    }
132

133
    pub(crate) fn num_lines(&self) -> usize {
4✔
134
        self.lines.len()
4✔
135
    }
136

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

153
    /// Set `style` for `line`, `col` if:
154
    /// 1. That line and column exist in `StyledBuffer`
155
    /// 2. `overwrite` is `true` or existing style is `Style::NoStyle` or `Style::Quotation`
156
    pub(crate) fn set_style(
5✔
157
        &mut self,
158
        line: usize,
159
        col: usize,
160
        style: ElementStyle,
161
        overwrite: bool,
162
    ) {
163
        if let Some(ref mut line) = self.lines.get_mut(line) {
5✔
164
            if let Some(StyledChar { style: s, .. }) = line.get_mut(col) {
10✔
165
                if overwrite || matches!(s, ElementStyle::NoStyle | ElementStyle::Quotation) {
10✔
166
                    *s = style;
5✔
167
                }
168
            }
169
        }
170
    }
171
}
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