notedeck

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

timed_serializer.rs (2421B)


      1 use std::time::{Duration, Instant};
      2 
      3 use notedeck::{storage, DataPath, DataPathType, Directory};
      4 use serde::{Deserialize, Serialize};
      5 use tracing::info;
      6 
      7 pub struct TimedSerializer<T: PartialEq + Copy + Serialize + for<'de> Deserialize<'de>> {
      8     directory: Directory,
      9     file_name: String,
     10     delay: Duration,
     11     last_saved: Instant,
     12     saved_item: Option<T>,
     13 }
     14 
     15 impl<T: PartialEq + Copy + Serialize + for<'de> Deserialize<'de>> TimedSerializer<T> {
     16     pub fn new(path: &DataPath, path_type: DataPathType, file_name: String) -> Self {
     17         let directory = Directory::new(path.path(path_type));
     18         let delay = Duration::from_millis(1000);
     19 
     20         Self {
     21             directory,
     22             file_name,
     23             delay,
     24             last_saved: Instant::now() - delay,
     25             saved_item: None,
     26         }
     27     }
     28 
     29     pub fn with_delay(mut self, delay: Duration) -> Self {
     30         self.delay = delay;
     31         self
     32     }
     33 
     34     fn should_save(&self) -> bool {
     35         self.last_saved.elapsed() >= self.delay
     36     }
     37 
     38     // returns whether successful
     39     pub fn try_save(&mut self, cur_item: T) -> bool {
     40         if self.should_save() {
     41             if let Some(saved_item) = self.saved_item {
     42                 if saved_item != cur_item {
     43                     return self.save(cur_item);
     44                 }
     45             } else {
     46                 return self.save(cur_item);
     47             }
     48         }
     49         false
     50     }
     51 
     52     pub fn get_item(&self) -> Option<T> {
     53         if self.saved_item.is_some() {
     54             return self.saved_item;
     55         }
     56 
     57         if let Ok(file_contents) = self.directory.get_file(self.file_name.clone()) {
     58             if let Ok(item) = serde_json::from_str::<T>(&file_contents) {
     59                 return Some(item);
     60             }
     61         } else {
     62             info!("Could not find file {}", self.file_name);
     63         }
     64 
     65         None
     66     }
     67 
     68     fn save(&mut self, cur_item: T) -> bool {
     69         if let Ok(serialized_item) = serde_json::to_string(&cur_item) {
     70             if storage::write_file(
     71                 &self.directory.file_path,
     72                 self.file_name.clone(),
     73                 &serialized_item,
     74             )
     75             .is_ok()
     76             {
     77                 info!("wrote item {}", serialized_item);
     78                 self.last_saved = Instant::now();
     79                 self.saved_item = Some(cur_item);
     80                 return true;
     81             }
     82         }
     83 
     84         false
     85     }
     86 }