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:
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
+ }
+}