Added Cache

This commit is contained in:
daladim 2021-02-25 00:53:50 +01:00
parent 624aec5dd1
commit 7197a5669a

View file

@ -1 +1,118 @@
//! This module provides a local cache for CalDAV data //! This module provides a local cache for CalDAV data
use std::path::PathBuf;
use std::path::Path;
use std::error::Error;
use serde::{Deserialize, Serialize};
use async_trait::async_trait;
use crate::traits::CalDavSource;
use crate::Calendar;
#[derive(Debug, PartialEq)]
pub struct Cache {
backing_file: PathBuf,
data: CachedData,
}
#[derive(Default, Debug, PartialEq, Serialize, Deserialize)]
struct CachedData {
calendars: Vec<Calendar>,
}
impl Cache {
/// Get the cache file
pub fn cache_file() -> PathBuf {
return PathBuf::from(String::from("~/.config/my-tasks/cache.json"))
}
/// Initialize a cache from the content of a backing file (if it exists, otherwise start with the default contents)
pub fn from_file(path: &Path) -> Result<Self, Box<dyn Error>> {
let data = match std::fs::File::open(path) {
Err(_) => {
CachedData::default()
},
Ok(file) => serde_json::from_reader(file)?,
};
Ok(Self{
backing_file: PathBuf::from(path),
data,
})
}
/// Initialize a cache with the default contents
pub fn new(path: &Path) -> Self {
Self{
backing_file: PathBuf::from(path),
data: CachedData::default(),
}
}
/// Store the current Cache to its backing file
fn save_to_file(&mut self) {
// Save the contents to the file
let path = &self.backing_file;
let file = match std::fs::File::create(path) {
Err(err) => {
log::warn!("Unable to save file {:?}: {}", path, err);
return;
},
Ok(f) => f,
};
if let Err(err) = serde_json::to_writer(file, &self.data) {
log::warn!("Unable to serialize: {}", err);
return;
};
}
}
impl Cache {
pub fn add_calendar(&mut self, calendar: Calendar) {
self.data.calendars.push(calendar);
}
}
#[async_trait]
impl CalDavSource for Cache {
async fn get_calendars(&self) -> Result<&Vec<Calendar>, Box<dyn Error>> {
Ok(&self.data.calendars)
}
async fn get_calendars_mut(&mut self) -> Result<Vec<&mut Calendar>, Box<dyn Error>> {
Ok(
self.data.calendars.iter_mut()
.collect()
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use url::Url;
use crate::calendar::SupportedComponents;
#[test]
fn serde_cache() {
let cache_path = PathBuf::from(String::from("cache.json"));
let mut cache = Cache::new(&cache_path);
let cal1 = Calendar::new("shopping list".to_string(),
Url::parse("https://caldav.com/shopping").unwrap(),
SupportedComponents::TODO);
cache.add_calendar(cal1);
cache.save_to_file();
let retrieved_cache = Cache::from_file(&cache_path).unwrap();
assert_eq!(cache, retrieved_cache);
}
}