summaryrefslogtreecommitdiff
path: root/support/texlab/src/debouncer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/src/debouncer.rs')
-rw-r--r--support/texlab/src/debouncer.rs55
1 files changed, 55 insertions, 0 deletions
diff --git a/support/texlab/src/debouncer.rs b/support/texlab/src/debouncer.rs
new file mode 100644
index 0000000000..b123dfc433
--- /dev/null
+++ b/support/texlab/src/debouncer.rs
@@ -0,0 +1,55 @@
+use std::time::{Duration, Instant};
+
+use anyhow::Result;
+
+pub struct Sender<T> {
+ tx: crossbeam_channel::Sender<(T, crossbeam_channel::Receiver<Instant>)>,
+}
+
+impl<T> Clone for Sender<T> {
+ fn clone(&self) -> Self {
+ Self {
+ tx: self.tx.clone(),
+ }
+ }
+}
+
+impl<T> Sender<T>
+where
+ T: Send + Sync + 'static,
+{
+ pub fn send(&self, msg: T, delay: Duration) -> Result<()> {
+ self.tx.send((msg, crossbeam_channel::after(delay)))?;
+ Ok(())
+ }
+}
+
+pub struct Receiver<T> {
+ rx: crossbeam_channel::Receiver<(T, crossbeam_channel::Receiver<Instant>)>,
+}
+
+impl<T> Clone for Receiver<T> {
+ fn clone(&self) -> Self {
+ Self {
+ rx: self.rx.clone(),
+ }
+ }
+}
+
+impl<T> Receiver<T> {
+ pub fn recv(&self) -> Result<T> {
+ let (mut last_msg, delay) = self.rx.recv()?;
+ delay.recv()?;
+ while let Ok((msg, delay)) = self.rx.try_recv() {
+ delay.recv()?;
+ last_msg = msg;
+ }
+
+ Ok(last_msg)
+ }
+}
+
+pub fn unbounded<T>() -> (Sender<T>, Receiver<T>) {
+ let (tx, rx) = crossbeam_channel::unbounded();
+ (Sender { tx }, Receiver { rx })
+}