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

veeso / tui-realm-stdlib / 22143900361

18 Feb 2026 02:31PM UTC coverage: 76.863% (+4.4%) from 72.486%
22143900361

Pull #58

github

web-flow
Merge 82269e219 into 237158c92
Pull Request #58: Remove unnecessary features

588 of 1352 new or added lines in 21 files covered. (43.49%)

40 existing lines in 15 files now uncovered.

3940 of 5126 relevant lines covered (76.86%)

4.91 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` provides a component which shows the progress. It is possible to set the style for the progress bar and the text shown above it.
2

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

11
use crate::prop_ext::CommonProps;
12

13
// -- Component
14

15
// TODO: we should remove this component in favor of just "LineGauge", as the implementation and inner workings are literally the same.
16

17
/// `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.
18
#[derive(Default)]
19
#[must_use]
20
pub struct ProgressBar {
21
    common: CommonProps,
22
    props: Props,
23
}
24

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

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

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

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

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

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

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

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

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

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

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

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

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

NEW
124
        if let Some(block) = self.common.get_block() {
×
NEW
125
            widget = widget.block(block);
×
NEW
126
        }
×
127

NEW
128
        render.render_widget(widget, area);
×
UNCOV
129
    }
×
130

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

136
        self.props.get(attr)
×
137
    }
×
138

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

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

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

159
#[cfg(test)]
160
mod test {
161

162
    use super::*;
163

164
    use pretty_assertions::assert_eq;
165
    use tuirealm::props::HorizontalAlignment;
166

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

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