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

veeso / tui-realm-stdlib / 22147789116

09 Feb 2026 04:20PM UTC coverage: 77.303% (+4.8%) from 72.482%
22147789116

push

github

hasezoey
refactor(table): switch to use "CommonProps"

18 of 90 new or added lines in 1 file covered. (20.0%)

405 existing lines in 20 files now uncovered.

3944 of 5102 relevant lines covered (77.3%)

4.92 hits per line

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

57.89
/src/components/progress_bar.rs
1
//! ## ProgressBar
2
//!
3
//! `ProgressBar` provides a component which shows the progress. It is possible to set the style for the progress bar and the text shown above it.
4

5
use tuirealm::command::{Cmd, CmdResult};
6
use tuirealm::props::{
7
    AttrValue, Attribute, Borders, Color, PropPayload, PropValue, Props, Style, TextModifiers,
8
    Title,
9
};
10
use tuirealm::ratatui::{layout::Rect, widgets::Gauge};
11
use tuirealm::{Frame, MockComponent, State};
12

13
use crate::prop_ext::CommonProps;
14

15
// -- Component
16

17
/// ## ProgressBar
18
///
19
/// provides a component which shows the progress. It is possible to set the style for the progress bar and the text shown above it.
20
#[derive(Default)]
21
#[must_use]
22
pub struct ProgressBar {
23
    common: CommonProps,
24
    props: Props,
25
}
26

27
impl ProgressBar {
28
    /// Set the main foreground color. This may get overwritten by individual text styles.
29
    pub fn foreground(mut self, fg: Color) -> Self {
4✔
30
        self.attr(Attribute::Foreground, AttrValue::Color(fg));
4✔
31
        self
4✔
32
    }
4✔
33

34
    /// Set the main background color. This may get overwritten by individual text styles.
35
    pub fn background(mut self, bg: Color) -> Self {
4✔
36
        self.attr(Attribute::Background, AttrValue::Color(bg));
4✔
37
        self
4✔
38
    }
4✔
39

40
    /// Set the main text modifiers. This may get overwritten by individual text styles.
41
    pub fn modifiers(mut self, m: TextModifiers) -> Self {
×
42
        self.attr(Attribute::TextProps, AttrValue::TextModifiers(m));
×
43
        self
×
UNCOV
44
    }
×
45

46
    /// Set the main style. This may get overwritten by individual text styles.
47
    ///
48
    /// This option will overwrite any previous [`foreground`](Self::foreground), [`background`](Self::background) and [`modifiers`](Self::modifiers)!
UNCOV
49
    pub fn style(mut self, style: Style) -> Self {
×
UNCOV
50
        self.attr(Attribute::Style, AttrValue::Style(style));
×
UNCOV
51
        self
×
UNCOV
52
    }
×
53

54
    /// Set a custom style for the border when the component is unfocused.
UNCOV
55
    pub fn inactive(mut self, s: Style) -> Self {
×
UNCOV
56
        self.attr(Attribute::FocusStyle, AttrValue::Style(s));
×
UNCOV
57
        self
×
UNCOV
58
    }
×
59

60
    /// Add a border to the component.
61
    pub fn borders(mut self, b: Borders) -> Self {
2✔
62
        self.attr(Attribute::Borders, AttrValue::Borders(b));
2✔
63
        self
2✔
64
    }
2✔
65

66
    /// Add a title to the component.
67
    pub fn title<T: Into<Title>>(mut self, title: T) -> Self {
2✔
68
        self.attr(Attribute::Title, AttrValue::Title(title.into()));
2✔
69
        self
2✔
70
    }
2✔
71

72
    /// Set a label text for the Bar.
73
    pub fn label<S: Into<String>>(mut self, s: S) -> Self {
2✔
74
        self.attr(Attribute::Text, AttrValue::String(s.into()));
2✔
75
        self
2✔
76
    }
2✔
77

78
    /// Set the initial progress value.
79
    pub fn progress(mut self, p: f64) -> Self {
4✔
80
        Self::assert_progress(p);
4✔
81
        self.attr(
4✔
82
            Attribute::Value,
4✔
83
            AttrValue::Payload(PropPayload::Single(PropValue::F64(p))),
4✔
84
        );
2✔
85
        self
4✔
86
    }
4✔
87

88
    fn assert_progress(p: f64) {
6✔
89
        assert!(
6✔
90
            (0.0..=1.0).contains(&p),
6✔
91
            "Progress value must be in range [0.0, 1.0]"
1✔
92
        );
93
    }
4✔
94
}
95

96
impl MockComponent for ProgressBar {
97
    fn view(&mut self, render: &mut Frame, area: Rect) {
×
98
        if !self.common.display {
×
99
            return;
×
100
        }
×
101

102
        // Text
103
        let label = self
×
UNCOV
104
            .props
×
105
            .get_or(Attribute::Text, AttrValue::String(String::default()))
×
106
            .unwrap_string();
×
107
        // Get percentage
108
        let percentage = self
×
109
            .props
×
UNCOV
110
            .get_or(
×
111
                Attribute::Value,
×
112
                AttrValue::Payload(PropPayload::Single(PropValue::F64(0.0))),
×
113
            )
UNCOV
114
            .unwrap_payload()
×
115
            .unwrap_single()
×
116
            .unwrap_f64();
×
117

118
        // Make progress bar
UNCOV
119
        let mut widget = Gauge::default()
×
120
            .style(self.common.style)
×
UNCOV
121
            .gauge_style(self.common.style)
×
122
            .label(label)
×
123
            .ratio(percentage)
×
124
            .use_unicode(true);
×
125

126
        if let Some(block) = self.common.get_block() {
×
127
            widget = widget.block(block);
×
128
        }
×
129

130
        render.render_widget(widget, area);
×
UNCOV
131
    }
×
132

133
    fn query(&self, attr: Attribute) -> Option<AttrValue> {
×
UNCOV
134
        if let Some(value) = self.common.get(attr) {
×
135
            return Some(value);
×
136
        }
×
137

UNCOV
138
        self.props.get(attr)
×
UNCOV
139
    }
×
140

141
    fn attr(&mut self, attr: Attribute, value: AttrValue) {
16✔
142
        if let Some(value) = self.common.set(attr, value) {
16✔
143
            if let Attribute::Value = attr {
4✔
144
                if let AttrValue::Payload(p) = value.clone() {
2✔
145
                    Self::assert_progress(p.unwrap_single().unwrap_f64());
2✔
146
                }
2✔
147
            }
2✔
148
            self.props.set(attr, value);
4✔
149
        }
12✔
150
    }
16✔
151

152
    fn state(&self) -> State {
2✔
153
        State::None
2✔
154
    }
2✔
155

UNCOV
156
    fn perform(&mut self, _cmd: Cmd) -> CmdResult {
×
UNCOV
157
        CmdResult::None
×
UNCOV
158
    }
×
159
}
160

161
#[cfg(test)]
162
mod test {
163

164
    use super::*;
165

166
    use pretty_assertions::assert_eq;
167
    use tuirealm::props::HorizontalAlignment;
168

169
    #[test]
170
    fn test_components_progress_bar() {
2✔
171
        let component = ProgressBar::default()
2✔
172
            .background(Color::Red)
2✔
173
            .foreground(Color::White)
2✔
174
            .progress(0.60)
2✔
175
            .title(Title::from("Downloading file...").alignment(HorizontalAlignment::Center))
2✔
176
            .label("60% - ETA 00:20")
2✔
177
            .borders(Borders::default());
2✔
178
        // Get value
1✔
179
        assert_eq!(component.state(), State::None);
2✔
180
    }
2✔
181

182
    #[test]
183
    #[should_panic = "Progress value must be in range [0.0, 1.0]"]
184
    fn test_components_progress_bar_bad_prog() {
2✔
185
        let _ = ProgressBar::default()
2✔
186
            .background(Color::Red)
2✔
187
            .foreground(Color::White)
2✔
188
            .progress(6.0)
2✔
189
            .title(Title::from("Downloading file...").alignment(HorizontalAlignment::Center))
2✔
190
            .label("60% - ETA 00:20")
2✔
191
            .borders(Borders::default());
2✔
192
    }
2✔
193
}
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