progressing/
bernoulli.rs

1use crate::{mapping, timing, Baring};
2use std::{
3    fmt::{self, Display},
4    ops::{Add, AddAssign, Div, Sub},
5};
6
7pub struct Config {}
8
9/// A progress-bar counting successes (e.g. `42 out of 60`) and respective attempts (e.g. `130`).
10///
11/// # Mini-Example
12///
13/// ```
14/// use progressing::{Baring, bernoulli::Bar as BernoulliBar};
15///
16/// /// Bernoulli-Bar counting successes (42 / 60) and attempts (# 130)
17/// /// [============>-----] (42 / 60 # 130)
18/// fn main() {
19///     println!("Bernoulli-Bar counting successes (42 / 60) and attempts (# 130)");
20///     let mut progress_bar = BernoulliBar::with_goal(60);
21///     progress_bar.set_len(20);
22///     progress_bar.set((42, 130));
23///     println!("{}", progress_bar);
24/// }
25/// ```
26#[derive(Debug)]
27pub struct Bar {
28    bar: mapping::Bar<usize>,
29    attempts: usize,
30}
31
32impl Bar {
33    pub fn with_goal(end: usize) -> Bar {
34        Bar {
35            bar: mapping::Bar::with_range(0, end),
36            attempts: 0,
37        }
38    }
39
40    pub fn timed(self) -> timing::Bar<Bar> {
41        timing::Bar::with(self)
42    }
43}
44
45impl Baring for Bar {
46    type Progress = Progress;
47
48    fn len(&self) -> usize {
49        self.bar.len()
50    }
51
52    fn set_len(&mut self, new_bar_len: usize) {
53        self.bar.set_len(new_bar_len)
54    }
55
56    fn progress(&self) -> Progress {
57        Progress {
58            successes: self.bar.progress(),
59            attempts: self.attempts,
60        }
61    }
62
63    fn set<P>(&mut self, outcome: P)
64    where
65        P: Into<Progress>,
66    {
67        let outcome = outcome.into();
68        self.bar.set(outcome.successes);
69        self.attempts = outcome.attempts;
70    }
71
72    fn start(&self) -> Progress {
73        Progress {
74            successes: self.bar.start(),
75            attempts: 0,
76        }
77    }
78
79    fn end(&self) -> Progress {
80        Progress {
81            successes: self.bar.end(),
82            attempts: 1,
83        }
84    }
85
86    fn has_progressed_significantly(&self) -> bool {
87        self.bar.has_progressed_significantly()
88    }
89
90    fn remember_significant_progress(&mut self) {
91        self.bar.remember_significant_progress()
92    }
93}
94
95impl Display for Bar {
96    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97        write!(f, "{} #{}", self.bar, self.attempts)
98    }
99}
100
101/// Just a simple struct capsuling access to successes and attempts.
102#[derive(Copy, Clone)]
103pub struct Progress {
104    pub successes: usize,
105    pub attempts: usize,
106}
107
108impl From<(usize, usize)> for Progress {
109    fn from((successes, attempts): (usize, usize)) -> Progress {
110        Progress {
111            successes,
112            attempts,
113        }
114    }
115}
116
117impl From<usize> for Progress {
118    fn from(successes: usize) -> Progress {
119        Progress {
120            successes,
121            attempts: successes,
122        }
123    }
124}
125
126impl From<bool> for Progress {
127    fn from(is_successful: bool) -> Progress {
128        Progress {
129            successes: if is_successful { 1 } else { 0 },
130            attempts: 1,
131        }
132    }
133}
134
135impl Add for Progress {
136    type Output = Progress;
137
138    fn add(self, other: Progress) -> Progress {
139        Progress {
140            successes: self.successes + other.successes,
141            attempts: self.attempts + other.attempts,
142        }
143    }
144}
145
146impl AddAssign for Progress {
147    fn add_assign(&mut self, other: Progress) {
148        *self = *self + other;
149    }
150}
151
152impl Sub for Progress {
153    type Output = Progress;
154
155    fn sub(self, subtrahend: Progress) -> Progress {
156        Progress {
157            successes: self.successes - subtrahend.successes,
158            attempts: self.attempts - subtrahend.attempts,
159        }
160    }
161}
162
163impl Div for Progress {
164    type Output = f64;
165
166    fn div(self, dividend: Progress) -> f64 {
167        self.successes as f64 / (dividend.successes as f64)
168    }
169}