1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
use tokio::time::Duration;

pub fn obtain_next_interval(
    current_cycle: &usize,
    cycle_ceiling: &usize,
    retry_interval: &Duration,
) -> Option<Duration> {
    if cycle_ceiling < current_cycle {
        return None
    }

    return if current_cycle <= &0 {
        Option::from(Duration::from_millis(*current_cycle as u64 * (retry_interval.as_secs() * 1000)))
    } else {
        Option::from(obtain_next_interval(&(current_cycle - 1), cycle_ceiling, retry_interval).unwrap()
            + Duration::from_millis(*current_cycle as u64 * (retry_interval.as_secs() * 1000)))
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn scenario_one() {
        let interval = Duration::from_millis(5000);

        assert_eq!(obtain_next_interval(&2, &5, &interval)
                       .unwrap(), Duration::from_millis(15000));
    }

    #[test]
    fn failing_scenario_one() {
        let interval = Duration::from_millis(5000);

        // This assert would fire and test will fail.
        // Please note, that private functions can be tested too!
        assert_eq!(obtain_next_interval(&5, &4,
                                        &interval), None);
    }
}