notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit a24a089e87bf86b7a9efd36726bf92172b8af2e9
parent 28af9c22720183179f5907ac421a79d3cf04b3b4
Author: kernelkind <kernelkind@gmail.com>
Date:   Mon, 13 Jan 2025 18:06:41 -0500

extract timing from AppSizeHandler to TimedSerializer

Signed-off-by: kernelkind <kernelkind@gmail.com>

Diffstat:
MCargo.lock | 1+
Mcrates/notedeck_chrome/Cargo.toml | 1+
Acrates/notedeck_chrome/src/timed_serializer.rs | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 88 insertions(+), 0 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -2530,6 +2530,7 @@ dependencies = [ "notedeck_columns", "puffin 0.19.1 (git+https://github.com/jb55/puffin?rev=70ff86d5503815219b01a009afd3669b7903a057)", "puffin_egui", + "serde", "serde_json", "strum", "tempfile", diff --git a/crates/notedeck_chrome/Cargo.toml b/crates/notedeck_chrome/Cargo.toml @@ -19,6 +19,7 @@ notedeck = { workspace = true } puffin = { workspace = true, optional = true } puffin_egui = { workspace = true, optional = true } serde_json = { workspace = true } +serde = { workspace = true } strum = { workspace = true } tokio = { workspace = true } tracing-appender = { workspace = true } diff --git a/crates/notedeck_chrome/src/timed_serializer.rs b/crates/notedeck_chrome/src/timed_serializer.rs @@ -0,0 +1,86 @@ +use std::time::{Duration, Instant}; + +use notedeck::{storage, DataPath, DataPathType, Directory}; +use serde::{Deserialize, Serialize}; +use tracing::info; + +pub struct TimedSerializer<T: PartialEq + Copy + Serialize + for<'de> Deserialize<'de>> { + directory: Directory, + file_name: String, + delay: Duration, + last_saved: Instant, + saved_item: Option<T>, +} + +impl<T: PartialEq + Copy + Serialize + for<'de> Deserialize<'de>> TimedSerializer<T> { + 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); + + Self { + directory, + file_name, + delay, + last_saved: Instant::now() - delay, + saved_item: None, + } + } + + pub fn with_delay(mut self, delay: Duration) -> Self { + self.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 let Some(saved_item) = self.saved_item { + if saved_item != cur_item { + return self.save(cur_item); + } + } else { + return self.save(cur_item); + } + } + false + } + + pub fn get_item(&self) -> Option<T> { + 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); + } + } else { + info!("Could not find file {}", self.file_name); + } + + None + } + + fn save(&mut self, cur_item: T) -> bool { + if let Ok(serialized_item) = serde_json::to_string(&cur_item) { + if storage::write_file( + &self.directory.file_path, + self.file_name.clone(), + &serialized_item, + ) + .is_ok() + { + info!("wrote item {}", serialized_item); + self.last_saved = Instant::now(); + self.saved_item = Some(cur_item); + return true; + } + } + + false + } +}