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

rust-lang / annotate-snippets-rs / 13907127047

17 Mar 2025 06:30PM UTC coverage: 61.679% (-24.1%) from 85.793%
13907127047

Pull #187

github

web-flow
Merge d44f85477 into 5c6ce17f3
Pull Request #187: refactor(#184)

636 of 729 new or added lines in 6 files covered. (87.24%)

276 existing lines in 1 file now uncovered.

779 of 1263 relevant lines covered (61.68%)

3.8 hits per line

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

86.67
/src/renderer/display/display_annotations.rs
1
use anstyle::Style;
2

3
use crate::{renderer::stylesheet::Stylesheet, snippet};
4

5
use super::{
6
    constants::{ERROR_TXT, HELP_TXT, INFO_TXT, NOTE_TXT, WARNING_TXT},
7
    display_text::DisplayTextFragment,
8
};
9

10
/// A type of the `Annotation` which may impact the sigils, style or text displayed.
11
///
12
/// There are several ways to uses this information when formatting the `DisplayList`:
13
///
14
/// * An annotation may display the name of the type like `error` or `info`.
15
/// * An underline for `Error` may be `^^^` while for `Warning` it could be `---`.
16
/// * `ColorStylesheet` may use different colors for different annotations.
17
#[derive(Debug, Clone, PartialEq)]
18
pub(crate) enum DisplayAnnotationType {
19
    None,
20
    Error,
21
    Warning,
22
    Info,
23
    Note,
24
    Help,
25
}
26

27
/// An inline text
28
/// An indicator of what part of the annotation a given `Annotation` is.
29
#[derive(Debug, Clone, PartialEq)]
30
pub(crate) enum DisplayAnnotationPart {
31
    /// A standalone, single-line annotation.
32
    Standalone,
33
    /// A continuation of a multi-line label of an annotation.
34
    LabelContinuation,
35
    /// A line starting a multiline annotation.
36
    MultilineStart(usize),
37
    /// A line ending a multiline annotation.
38
    MultilineEnd(usize),
39
}
40

41
/// Inline annotation which can be used in either Raw or Source line.
42
#[derive(Clone, Debug, PartialEq)]
43
pub(crate) struct Annotation<'a> {
44
    pub(crate) annotation_type: DisplayAnnotationType,
45
    pub(crate) id: Option<&'a str>,
46
    pub(crate) label: Vec<DisplayTextFragment<'a>>,
47
}
48

49
#[derive(Clone, Debug, PartialEq)]
50
pub(crate) struct DisplaySourceAnnotation<'a> {
51
    pub(crate) annotation: Annotation<'a>,
52
    pub(crate) range: (usize, usize),
53
    pub(crate) annotation_type: DisplayAnnotationType,
54
    pub(crate) annotation_part: DisplayAnnotationPart,
55
}
56

57
impl DisplaySourceAnnotation<'_> {
58
    pub(crate) fn has_label(&self) -> bool {
6✔
59
        !self
4✔
60
            .annotation
61
            .label
62
            .iter()
63
            .all(|label| label.content.is_empty())
6✔
64
    }
65

66
    // Length of this annotation as displayed in the stderr output
67
    pub(crate) fn len(&self) -> usize {
3✔
68
        // Account for usize underflows
69
        if self.range.1 > self.range.0 {
6✔
70
            self.range.1 - self.range.0
6✔
71
        } else {
NEW
72
            self.range.0 - self.range.1
×
73
        }
74
    }
75

76
    pub(crate) fn takes_space(&self) -> bool {
4✔
77
        // Multiline annotations always have to keep vertical space.
78
        matches!(
4✔
79
            self.annotation_part,
4✔
80
            DisplayAnnotationPart::MultilineStart(_) | DisplayAnnotationPart::MultilineEnd(_)
81
        )
82
    }
83
}
84

85
impl From<snippet::Level> for DisplayAnnotationType {
86
    fn from(at: snippet::Level) -> Self {
8✔
87
        match at {
6✔
88
            snippet::Level::Error => DisplayAnnotationType::Error,
8✔
89
            snippet::Level::Warning => DisplayAnnotationType::Warning,
2✔
90
            snippet::Level::Info => DisplayAnnotationType::Info,
1✔
91
            snippet::Level::Note => DisplayAnnotationType::Note,
1✔
92
            snippet::Level::Help => DisplayAnnotationType::Help,
1✔
93
        }
94
    }
95
}
96

97
#[inline]
98
pub(crate) fn annotation_type_str(annotation_type: &DisplayAnnotationType) -> &'static str {
4✔
99
    match annotation_type {
6✔
100
        DisplayAnnotationType::Error => ERROR_TXT,
5✔
101
        DisplayAnnotationType::Help => HELP_TXT,
1✔
102
        DisplayAnnotationType::Info => INFO_TXT,
1✔
103
        DisplayAnnotationType::Note => NOTE_TXT,
1✔
NEW
104
        DisplayAnnotationType::Warning => WARNING_TXT,
×
NEW
105
        DisplayAnnotationType::None => "",
×
106
    }
107
}
108

109
pub(crate) fn annotation_type_len(annotation_type: &DisplayAnnotationType) -> usize {
6✔
110
    match annotation_type {
5✔
111
        DisplayAnnotationType::Error => ERROR_TXT.len(),
5✔
112
        DisplayAnnotationType::Help => HELP_TXT.len(),
1✔
113
        DisplayAnnotationType::Info => INFO_TXT.len(),
1✔
114
        DisplayAnnotationType::Note => NOTE_TXT.len(),
1✔
NEW
115
        DisplayAnnotationType::Warning => WARNING_TXT.len(),
×
116
        DisplayAnnotationType::None => 0,
4✔
117
    }
118
}
119

120
pub(crate) fn get_annotation_style<'a>(
5✔
121
    annotation_type: &DisplayAnnotationType,
122
    stylesheet: &'a Stylesheet,
123
) -> &'a Style {
124
    match annotation_type {
9✔
125
        DisplayAnnotationType::Error => stylesheet.error(),
5✔
126
        DisplayAnnotationType::Warning => stylesheet.warning(),
2✔
127
        DisplayAnnotationType::Info => stylesheet.info(),
1✔
128
        DisplayAnnotationType::Note => stylesheet.note(),
1✔
129
        DisplayAnnotationType::Help => stylesheet.help(),
1✔
NEW
130
        DisplayAnnotationType::None => stylesheet.none(),
×
131
    }
132
}
133

134
#[inline]
135
pub(crate) fn is_annotation_empty(annotation: &Annotation<'_>) -> bool {
7✔
136
    annotation
7✔
NEW
137
        .label
×
138
        .iter()
139
        .all(|fragment| fragment.content.is_empty())
14✔
140
}
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