Skip to content

Commit 8a36a20

Browse files
jxsFleshgrinder
authored andcommitted
Added Rust debounce solution (#112)
1 parent 1584e4c commit 8a36a20

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed

problems/debounce/debounce.rs

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
use std::time::{Duration, Instant};
2+
3+
fn debounce<F: FnMut()>(mut f: F, timeout: u64, pass: bool) -> impl FnMut() {
4+
let dur = Duration::from_millis(timeout);
5+
let mut active: Option<Instant> = None;
6+
move || {
7+
match active {
8+
Some(inst) if (inst.elapsed() <= dur) && !pass => {
9+
active = Some(Instant::now());
10+
}
11+
Some(_) | None => {
12+
f();
13+
active = Some(Instant::now());
14+
}
15+
}
16+
}
17+
}
18+
19+
fn main() {
20+
let mut debounced = debounce(|| {println!("debounce!");}, 5, false);
21+
debounced();
22+
}
23+
24+
25+
mod tests {
26+
use super::debounce;
27+
use std::time::Duration;
28+
use std::thread::sleep;
29+
30+
#[test]
31+
fn function_is_called_first_time() {
32+
let mut start = 0;
33+
{
34+
let mut debounced = debounce(|| {
35+
start += 1;
36+
}, 10, false);
37+
debounced();
38+
}
39+
assert_eq!(1, start);
40+
}
41+
42+
#[test]
43+
fn function_is_not_called_if_timeout_hasnt_elapsed() {
44+
let mut start = 0;
45+
{
46+
let mut debounced = debounce(|| {
47+
start += 1;
48+
}, 100, false);
49+
debounced();
50+
debounced();
51+
}
52+
assert_eq!(1, start);
53+
}
54+
55+
#[test]
56+
fn function_iscalled_after_timeout_has_elapsed() {
57+
let mut start = 0;
58+
let dur = 100;
59+
{
60+
let mut debounced = debounce(|| {
61+
start += 1;
62+
}, dur, false);
63+
debounced();
64+
sleep(Duration::from_millis(dur));
65+
debounced();
66+
}
67+
assert_eq!(2, start);
68+
}
69+
70+
#[test]
71+
fn timeout_is_restarted_if_function_is_called_before_timeout_has_elapsed() {
72+
let mut start = 0;
73+
let dur = 100;
74+
{
75+
let mut debounced = debounce(|| {
76+
start += 1;
77+
}, dur, false);
78+
debounced();
79+
sleep(Duration::from_millis(dur - 20));
80+
debounced();
81+
sleep(Duration::from_millis(20));
82+
debounced();
83+
}
84+
assert_eq!(1, start);
85+
}
86+
87+
#[test]
88+
fn function_is_called_after_timeout_is_restarted() {
89+
let mut start = 0;
90+
let dur = 100;
91+
{
92+
let mut debounced = debounce(|| {
93+
start += 1;
94+
}, dur, false);
95+
debounced();
96+
sleep(Duration::from_millis(dur - 20));
97+
debounced();
98+
sleep(Duration::from_millis(20));
99+
debounced();
100+
sleep(Duration::from_millis(dur));
101+
debounced();
102+
}
103+
assert_eq!(2, start);
104+
}
105+
106+
#[test]
107+
fn function_is_called_is_pass() {
108+
let mut start = 0;
109+
let dur = 100;
110+
{
111+
let mut debounced = debounce(|| {
112+
start += 1;
113+
}, dur, true);
114+
debounced();
115+
debounced();
116+
debounced();
117+
}
118+
assert_eq!(3, start);
119+
}
120+
}

0 commit comments

Comments
 (0)