use debounce::{EventBuffer, State};
use getopts::Options;
use std::env;
use std::error::Error;
use std::io::{self, Write};
use std::sync::{Arc, Mutex};
use std::thread::{self, JoinHandle};
use std::time::Duration;
fn put(mutex: &Mutex<EventBuffer<String>>, debouncer: &JoinHandle<()>, data: String) {
mutex.lock().unwrap().put(data);
debouncer.thread().unpark();
}
fn get(mutex: &Mutex<EventBuffer<String>>) -> State<String> {
mutex.lock().unwrap().get()
}
fn main() -> Result<(), Box<dyn Error>> {
let args: Vec<String> = env::args().collect();
let mut opts = Options::new();
opts.reqopt("t", "", "debounce timeout in milliseconds", "TIMEOUT");
let matches = opts.parse(&args[1..])?;
let timeout = matches.opt_str("t").unwrap().parse()?;
let mutex = Arc::new(Mutex::new(EventBuffer::new(Duration::from_millis(timeout))));
let mutex_clone = mutex.clone();
let mut stdout = io::stdout();
let debouncer = thread::spawn(move || loop {
match get(&mutex_clone) {
State::Empty => thread::park(),
State::Wait(duration) => thread::sleep(duration),
State::Ready(data) => {
stdout.write_all(data.as_bytes()).ok();
}
}
});
loop {
let mut buffer = String::new();
let stdin = io::stdin();
stdin.read_line(&mut buffer)?;
put(&mutex, &debouncer, buffer);
}
}