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

rust-lang / annotate-snippets-rs / 15862044996

24 Jun 2025 09:37PM UTC coverage: 86.621%. Remained the same
15862044996

Pull #222

github

web-flow
Merge a0d26c6aa into a81dc31d2
Pull Request #222: test: Ensure all examples have a test

1392 of 1607 relevant lines covered (86.62%)

4.5 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 {
4✔
27
        StyledChar { ch, style }
28
    }
29
}
30

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

36
    fn ensure_lines(&mut self, line: usize) {
4✔
37
        if line >= self.lines.len() {
6✔
38
            self.lines.resize(line + 1, Vec::new());
4✔
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() {
5✔
49
            let mut current_style = stylesheet.none;
5✔
50
            for StyledChar { ch, style } in line {
10✔
51
                let ch_style = style.color_spec(&level, stylesheet);
5✔
52
                if ch_style != current_style {
4✔
53
                    if !line.is_empty() {
2✔
54
                        write!(str, "{}", current_style.render_reset())?;
2✔
55
                    }
56
                    current_style = ch_style;
2✔
57
                    write!(str, "{}", current_style.render())?;
2✔
58
                }
59
                write!(str, "{ch}")?;
6✔
60
            }
61
            write!(str, "{}", current_style.render_reset())?;
8✔
62
            if i != self.lines.len() - 1 {
3✔
63
                writeln!(str)?;
7✔
64
            }
65
        }
66
        Ok(())
4✔
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);
5✔
74
        if col >= self.lines[line].len() {
6✔
75
            self.lines[line].resize(col + 1, StyledChar::SPACE);
4✔
76
        }
77
        self.lines[line][col] = StyledChar::new(chr, style);
6✔
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;
6✔
85
        for c in string.chars() {
10✔
86
            self.putc(line, n, c, style);
6✔
87
            n += 1;
10✔
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) {
6✔
94
        if line >= self.lines.len() {
4✔
95
            self.puts(line, 0, string, style);
6✔
96
        } else {
97
            let col = self.lines[line].len();
6✔
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()));
3✔
107
        for (i, c) in string.chars().enumerate() {
4✔
108
            self.lines[line][start + i] = StyledChar::new(c, ElementStyle::LineNumber);
1✔
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);
9✔
116
        let string_len = string.chars().count();
7✔
117

118
        if !self.lines[line].is_empty() {
7✔
119
            // Push the old content over to make room for new content
120
            for _ in 0..string_len {
12✔
121
                self.lines[line].insert(0, StyledChar::SPACE);
7✔
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()
4✔
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) {
2✔
159
            if let Some(StyledChar { style: s, .. }) = line.get_mut(col) {
6✔
160
                if overwrite || matches!(s, ElementStyle::NoStyle | ElementStyle::Quotation) {
6✔
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

© 2025 Coveralls, Inc