1
//!
2
//! A utility function to easily print progress information for procedures that
3
//! take a fixed number of steps. In particular, avoids writing too many
4
//! progress indications.
5
//!
6

            
7
/// The struct that can be initialised to keep track of progress counters.
8
pub struct Progress<F: Fn(usize, usize)> {
9
    maximum: usize,
10
    counter: usize,
11

            
12
    message: F,
13
}
14

            
15
impl<F: Fn(usize, usize)> Progress<F> {
16
    /// Create a new progress tracker with a given maximum.
17
26
    pub fn new(message: F, maximum: usize) -> Progress<F> {
18
26
        Progress {
19
26
            message,
20
26
            maximum,
21
26
            counter: 0,
22
26
        }
23
26
    }
24

            
25
    /// Increase the progress with the given amount, prints periodic progress
26
    /// messages.
27
164606
    pub fn add(&mut self, amount: usize) {
28
164606
        let increment = (self.maximum / 100usize).max(1);
29
164606

            
30
164606
        if (self.counter + amount) / increment > self.counter / increment {
31
2158
            // Print a progress message when the increment increased.
32
2158
            (self.message)(self.counter, increment);
33
163000
        }
34

            
35
164606
        self.counter += amount;
36
164606
    }
37
}
38

            
39
#[cfg(test)]
40
mod tests {
41
    use super::Progress;
42

            
43
    #[test]
44
1
    fn test_progress() {
45
1
        // Test with extreme values.
46
1
        let _min = Progress::new(|_, _| {}, 0);
47
1

            
48
1
        let _progress = Progress::new(|_, _| {}, 1000);
49
1
    }
50
}