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

rust-lang / annotate-snippets-rs / 14714242977

28 Apr 2025 05:42PM UTC coverage: 86.774% (-0.4%) from 87.161%
14714242977

push

github

web-flow
Merge pull request #201 from Muscraft/migrate-fixture-tests

Migrate fixture tests

1345 of 1550 relevant lines covered (86.77%)

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

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

42
    pub(crate) fn render(
7✔
43
        &self,
44
        level: Level<'_>,
45
        stylesheet: &Stylesheet,
46
    ) -> Result<String, fmt::Error> {
47
        let mut str = String::new();
8✔
48
        for (i, line) in self.lines.iter().enumerate() {
24✔
49
            let mut current_style = stylesheet.none;
8✔
50
            for StyledChar { ch, style } in line {
20✔
51
                let ch_style = style.color_spec(&level, stylesheet);
6✔
52
                if ch_style != current_style {
7✔
53
                    if !line.is_empty() {
1✔
54
                        write!(str, "{}", current_style.render_reset())?;
3✔
55
                    }
56
                    current_style = ch_style;
2✔
57
                    write!(str, "{}", current_style.render())?;
3✔
58
                }
59
                write!(str, "{ch}")?;
13✔
60
            }
61
            write!(str, "{}", current_style.render_reset())?;
16✔
62
            if i != self.lines.len() - 1 {
15✔
63
                writeln!(str)?;
7✔
64
            }
65
        }
66
        Ok(str)
7✔
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);
7✔
74
        if col >= self.lines[line].len() {
7✔
75
            self.lines[line].resize(col + 1, StyledChar::SPACE);
4✔
76
        }
77
        self.lines[line][col] = StyledChar::new(chr, style);
7✔
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) {
6✔
84
        let mut n = col;
5✔
85
        for c in string.chars() {
14✔
86
            self.putc(line, n, c, style);
7✔
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) {
5✔
94
        if line >= self.lines.len() {
6✔
95
            self.puts(line, 0, string, style);
5✔
96
        } else {
97
            let col = self.lines[line].len();
5✔
98
            self.puts(line, col, string, style);
4✔
99
        }
100
    }
101

102
    /// For given `line` inserts `string` with `style` before old content of that line,
103
    /// adding lines if needed
104
    pub(crate) fn prepend(&mut self, line: usize, string: &str, style: ElementStyle) {
7✔
105
        self.ensure_lines(line);
5✔
106
        let string_len = string.chars().count();
6✔
107

108
        if !self.lines[line].is_empty() {
5✔
109
            // Push the old content over to make room for new content
110
            for _ in 0..string_len {
11✔
111
                self.lines[line].insert(0, StyledChar::SPACE);
6✔
112
            }
113
        }
114

115
        self.puts(line, 0, string, style);
6✔
116
    }
117

118
    pub(crate) fn num_lines(&self) -> usize {
3✔
119
        self.lines.len()
6✔
120
    }
121

122
    /// Set `style` for `line`, `col_start..col_end` range if:
123
    /// 1. That line and column range exist in `StyledBuffer`
124
    /// 2. `overwrite` is `true` or existing style is `Style::NoStyle` or `Style::Quotation`
125
    pub(crate) fn set_style_range(
1✔
126
        &mut self,
127
        line: usize,
128
        col_start: usize,
129
        col_end: usize,
130
        style: ElementStyle,
131
        overwrite: bool,
132
    ) {
133
        for col in col_start..col_end {
2✔
134
            self.set_style(line, col, style, overwrite);
1✔
135
        }
136
    }
137

138
    /// Set `style` for `line`, `col` if:
139
    /// 1. That line and column exist in `StyledBuffer`
140
    /// 2. `overwrite` is `true` or existing style is `Style::NoStyle` or `Style::Quotation`
141
    pub(crate) fn set_style(
1✔
142
        &mut self,
143
        line: usize,
144
        col: usize,
145
        style: ElementStyle,
146
        overwrite: bool,
147
    ) {
148
        if let Some(ref mut line) = self.lines.get_mut(line) {
1✔
149
            if let Some(StyledChar { style: s, .. }) = line.get_mut(col) {
2✔
150
                if overwrite || matches!(s, ElementStyle::NoStyle | ElementStyle::Quotation) {
2✔
151
                    *s = style;
1✔
152
                }
153
            }
154
        }
155
    }
156
}
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