notedeck: add debouncer util
I wanted this separate from the timed serializer so I could use it for other things Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
35
crates/notedeck/src/debouncer.rs
Normal file
35
crates/notedeck/src/debouncer.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
/// A simple debouncer that tracks when an action was last performed
|
||||
/// and determines if enough time has passed to perform it again.
|
||||
#[derive(Debug)]
|
||||
pub struct Debouncer {
|
||||
delay: Duration,
|
||||
last_action: Instant,
|
||||
}
|
||||
|
||||
impl Debouncer {
|
||||
/// Creates a new Debouncer with the specified delay
|
||||
pub fn new(delay: Duration) -> Self {
|
||||
Self {
|
||||
delay,
|
||||
last_action: Instant::now() - delay, // Start ready to act
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets a new delay value and returns self for method chaining
|
||||
pub fn with_delay(mut self, delay: Duration) -> Self {
|
||||
self.delay = delay;
|
||||
self
|
||||
}
|
||||
|
||||
/// Checks if enough time has passed since the last action
|
||||
pub fn should_act(&self) -> bool {
|
||||
self.last_action.elapsed() >= self.delay
|
||||
}
|
||||
|
||||
/// Marks an action as performed, updating the timestamp
|
||||
pub fn bounce(&mut self) {
|
||||
self.last_action = Instant::now();
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ mod accounts;
|
||||
mod app;
|
||||
mod args;
|
||||
mod context;
|
||||
pub mod debouncer;
|
||||
mod error;
|
||||
pub mod filter;
|
||||
pub mod fonts;
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use crate::debouncer::Debouncer;
|
||||
use crate::{storage, DataPath, DataPathType, Directory};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::info;
|
||||
use std::time::Duration;
|
||||
use tracing::info; // Adjust this import path as needed
|
||||
|
||||
pub struct TimedSerializer<T: PartialEq + Copy + Serialize + for<'de> Deserialize<'de>> {
|
||||
directory: Directory,
|
||||
file_name: String,
|
||||
delay: Duration,
|
||||
last_saved: Instant,
|
||||
debouncer: Debouncer,
|
||||
saved_item: Option<T>,
|
||||
}
|
||||
|
||||
@@ -16,28 +15,24 @@ impl<T: PartialEq + Copy + Serialize + for<'de> Deserialize<'de>> TimedSerialize
|
||||
pub fn new(path: &DataPath, path_type: DataPathType, file_name: String) -> Self {
|
||||
let directory = Directory::new(path.path(path_type));
|
||||
let delay = Duration::from_millis(1000);
|
||||
let debouncer = Debouncer::new(delay);
|
||||
|
||||
Self {
|
||||
directory,
|
||||
file_name,
|
||||
delay,
|
||||
last_saved: Instant::now() - delay,
|
||||
debouncer,
|
||||
saved_item: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_delay(mut self, delay: Duration) -> Self {
|
||||
self.delay = delay;
|
||||
self.debouncer = self.debouncer.with_delay(delay);
|
||||
self
|
||||
}
|
||||
|
||||
fn should_save(&self) -> bool {
|
||||
self.last_saved.elapsed() >= self.delay
|
||||
}
|
||||
|
||||
// returns whether successful
|
||||
pub fn try_save(&mut self, cur_item: T) -> bool {
|
||||
if self.should_save() {
|
||||
if self.debouncer.should_act() {
|
||||
if let Some(saved_item) = self.saved_item {
|
||||
if saved_item != cur_item {
|
||||
return self.save(cur_item);
|
||||
@@ -53,7 +48,6 @@ impl<T: PartialEq + Copy + Serialize + for<'de> Deserialize<'de>> TimedSerialize
|
||||
if self.saved_item.is_some() {
|
||||
return self.saved_item;
|
||||
}
|
||||
|
||||
if let Ok(file_contents) = self.directory.get_file(self.file_name.clone()) {
|
||||
if let Ok(item) = serde_json::from_str::<T>(&file_contents) {
|
||||
return Some(item);
|
||||
@@ -61,7 +55,6 @@ impl<T: PartialEq + Copy + Serialize + for<'de> Deserialize<'de>> TimedSerialize
|
||||
} else {
|
||||
info!("Could not find file {}", self.file_name);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
@@ -75,12 +68,11 @@ impl<T: PartialEq + Copy + Serialize + for<'de> Deserialize<'de>> TimedSerialize
|
||||
.is_ok()
|
||||
{
|
||||
info!("wrote item {}", serialized_item);
|
||||
self.last_saved = Instant::now();
|
||||
self.debouncer.bounce();
|
||||
self.saved_item = Some(cur_item);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user