From 721520dae41c988b51cccc1bc4abe68982e19014 Mon Sep 17 00:00:00 2001 From: pantonshire Date: Sun, 30 Apr 2023 15:22:29 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20remove=20DebouncerController=20from?= =?UTF-8?q?=20public=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib.rs | 62 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1839dec..709f71b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,10 @@ use std::{ /// finished waiting, it will emit a single event via a `mpsc` channel. pub struct Debouncer { thread: Option>, + // This is reference counted because the debouncer thread needs access to the controller, and + // the debouncer itself hasn't been created yet when the debouncer thread is created so we + // can't give it an `Arc>`. Besides, the thread probably shouldn't have access to + // its own join handle! controller: Arc>, } @@ -19,7 +23,7 @@ impl Debouncer where T: Send + 'static, { - pub fn start_new(debounce_time: Duration) -> Result<(Self, mpsc::Receiver), io::Error> { + pub fn new(debounce_time: Duration) -> Result<(Self, mpsc::Receiver), io::Error> { let controller = Arc::new(DebouncerController { state: Mutex::new(DebouncerState::new()), main_cvar: Condvar::new(), @@ -35,17 +39,53 @@ where Ok((Self { thread: Some(thread), controller }, rx)) } + + pub fn new_arc(debounce_time: Duration) + -> Result<(Arc, mpsc::Receiver), io::Error> + { + Self::new(debounce_time) + .map(|(this, rx)| (Arc::new(this), rx)) + } } impl Debouncer { - pub fn controller(&self) -> &Arc> { - &self.controller + /// Send the debouncer a raw event that should be debounced. The + /// [`mpsc::Receiver`](mpsc::Receiver) associated with this debouncer will receive a message + /// after at least the amount of time specified when the debouncer was created. + /// + /// The debouncer collects event data into an element of type `T`; the provided function `f` + /// specifies how to combine the new event data with the existing event data `Option` to + /// produce a new `T`. For example, if `T = Vec`, then `f` could be a function which pushes + /// to the vec: + /// + /// ```no_run + /// debouncer.debounce(e, |acc, e| { + /// let mut acc = acc.unwrap_or_default(); + /// acc.push(e); + /// acc + /// }) + /// ``` + pub fn debounce(&self, event_data: E, f: F) + where + F: FnOnce(Option, E) -> T, + { + self.controller.notify_event(event_data, f) + } +} + +impl Debouncer> { + pub fn debounce_push(&self, event_data: T) { + self.debounce(event_data, |acc, event_data| { + let mut acc = acc.unwrap_or_default(); + acc.push(event_data); + acc + }); } } impl Drop for Debouncer { fn drop(&mut self) { - self.controller().notify_shutdown(); + self.controller.notify_shutdown(); let thread = self.thread .take() @@ -58,7 +98,7 @@ impl Drop for Debouncer { } } -pub struct DebouncerController { +struct DebouncerController { state: Mutex>, /// Condvar for notifying the debouncer that it has become dirty or that it should shutdown. main_cvar: Condvar, @@ -81,7 +121,7 @@ impl DebouncerController { /// acc /// } /// ``` - pub fn notify_event(&self, event_data: E, f: F) + fn notify_event(&self, event_data: E, f: F) where F: FnOnce(Option, E) -> T, { @@ -100,16 +140,6 @@ impl DebouncerController { } } -impl DebouncerController> { - pub fn notify_event_push(&self, event_data: T) { - self.notify_event(event_data, |acc, event_data| { - let mut acc = acc.unwrap_or_default(); - acc.push(event_data); - acc - }); - } -} - struct DebouncerState { /// The debounced data we have received so far. acc: Option,