Added Cache
This commit is contained in:
parent
624aec5dd1
commit
7197a5669a
1 changed files with 118 additions and 1 deletions
119
src/cache.rs
119
src/cache.rs
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue