pub struct Cache { /* private fields */ }Expand description
A CalDAV source that stores its items in a local folder.
It automatically updates the content of the folder when dropped (see its Drop implementation), but you can also manually call Cache::save_to_folder
Most of its functionality is provided by the CalDavSource async trait it implements.
However, since these functions do not need to be actually async, non-async versions of them are also provided for better convenience. See Cache::get_calendar_sync for example
Implementations§
Source§impl Cache
impl Cache
Sourcepub fn cache_folder() -> PathBuf
pub fn cache_folder() -> PathBuf
Get the path to the cache folder
Sourcepub fn from_folder(folder: &Path) -> Result<Self, Box<dyn Error>>
pub fn from_folder(folder: &Path) -> Result<Self, Box<dyn Error>>
Initialize a cache from the content of a valid backing folder if it exists. Returns an error otherwise
Examples found in repository?
23pub async fn initial_sync(cache_folder: &str) -> CalDavProvider {
24 let cache_path = Path::new(cache_folder);
25
26 let client = Client::new(URL, USERNAME, PASSWORD).unwrap();
27 let cache = match Cache::from_folder(&cache_path) {
28 Ok(cache) => cache,
29 Err(err) => {
30 log::warn!("Invalid cache file: {}. Using a default cache", err);
31 Cache::new(&cache_path)
32 }
33 };
34 let mut provider = CalDavProvider::new(client, cache);
35
36
37 let cals = provider.local().get_calendars().await.unwrap();
38 println!("---- Local items, before sync -----");
39 kitchen_fridge::utils::print_calendar_list(&cals).await;
40
41 println!("Starting a sync...");
42 println!("Depending on your RUST_LOG value, you may see more or less details about the progress.");
43 // Note that we could use sync_with_feedback() to have better and formatted feedback
44 if provider.sync().await == false {
45 log::warn!("Sync did not complete, see the previous log lines for more info. You can safely start a new sync.");
46 }
47 provider.local().save_to_folder().unwrap();
48
49 println!("---- Local items, after sync -----");
50 let cals = provider.local().get_calendars().await.unwrap();
51 kitchen_fridge::utils::print_calendar_list(&cals).await;
52
53 provider
54}Sourcepub fn new(folder_path: &Path) -> Self
pub fn new(folder_path: &Path) -> Self
Initialize a cache with the default contents
Examples found in repository?
23pub async fn initial_sync(cache_folder: &str) -> CalDavProvider {
24 let cache_path = Path::new(cache_folder);
25
26 let client = Client::new(URL, USERNAME, PASSWORD).unwrap();
27 let cache = match Cache::from_folder(&cache_path) {
28 Ok(cache) => cache,
29 Err(err) => {
30 log::warn!("Invalid cache file: {}. Using a default cache", err);
31 Cache::new(&cache_path)
32 }
33 };
34 let mut provider = CalDavProvider::new(client, cache);
35
36
37 let cals = provider.local().get_calendars().await.unwrap();
38 println!("---- Local items, before sync -----");
39 kitchen_fridge::utils::print_calendar_list(&cals).await;
40
41 println!("Starting a sync...");
42 println!("Depending on your RUST_LOG value, you may see more or less details about the progress.");
43 // Note that we could use sync_with_feedback() to have better and formatted feedback
44 if provider.sync().await == false {
45 log::warn!("Sync did not complete, see the previous log lines for more info. You can safely start a new sync.");
46 }
47 provider.local().save_to_folder().unwrap();
48
49 println!("---- Local items, after sync -----");
50 let cals = provider.local().get_calendars().await.unwrap();
51 kitchen_fridge::utils::print_calendar_list(&cals).await;
52
53 provider
54}Sourcepub fn save_to_folder(&self) -> Result<(), Error>
pub fn save_to_folder(&self) -> Result<(), Error>
Store the current Cache to its backing folder
Note that this is automatically called when self is dropped
Examples found in repository?
23pub async fn initial_sync(cache_folder: &str) -> CalDavProvider {
24 let cache_path = Path::new(cache_folder);
25
26 let client = Client::new(URL, USERNAME, PASSWORD).unwrap();
27 let cache = match Cache::from_folder(&cache_path) {
28 Ok(cache) => cache,
29 Err(err) => {
30 log::warn!("Invalid cache file: {}. Using a default cache", err);
31 Cache::new(&cache_path)
32 }
33 };
34 let mut provider = CalDavProvider::new(client, cache);
35
36
37 let cals = provider.local().get_calendars().await.unwrap();
38 println!("---- Local items, before sync -----");
39 kitchen_fridge::utils::print_calendar_list(&cals).await;
40
41 println!("Starting a sync...");
42 println!("Depending on your RUST_LOG value, you may see more or less details about the progress.");
43 // Note that we could use sync_with_feedback() to have better and formatted feedback
44 if provider.sync().await == false {
45 log::warn!("Sync did not complete, see the previous log lines for more info. You can safely start a new sync.");
46 }
47 provider.local().save_to_folder().unwrap();
48
49 println!("---- Local items, after sync -----");
50 let cals = provider.local().get_calendars().await.unwrap();
51 kitchen_fridge::utils::print_calendar_list(&cals).await;
52
53 provider
54}More examples
43async fn add_items_and_sync_again(provider: &mut CalDavProvider) {
44 println!("\nNow, we'll add a calendar and a few tasks and run the sync again.");
45 pause();
46
47 // Create a new calendar...
48 let new_calendar_url: Url = EXAMPLE_CREATED_CALENDAR_URL.parse().unwrap();
49 let new_calendar_name = "A brave new calendar".to_string();
50 if let Err(_err) = provider.local_mut()
51 .create_calendar(new_calendar_url.clone(), new_calendar_name.clone(), SupportedComponents::TODO, Some("#ff8000".parse().unwrap()))
52 .await {
53 println!("Unable to add calendar, maybe it exists already. We're not adding it after all.");
54 }
55
56 // ...and add a task in it
57 let new_name = "This is a new task in a new calendar";
58 let new_task = Task::new(String::from(new_name), true, &new_calendar_url);
59 provider.local().get_calendar(&new_calendar_url).await.unwrap()
60 .lock().unwrap().add_item(Item::Task(new_task)).await.unwrap();
61
62
63 // Also create a task in a previously existing calendar
64 let changed_calendar_url: Url = EXAMPLE_EXISTING_CALENDAR_URL.parse().unwrap();
65 let new_task_name = "This is a new task we're adding as an example, with ÜTF-8 characters";
66 let new_task = Task::new(String::from(new_task_name), false, &changed_calendar_url);
67 let new_url = new_task.url().clone();
68 provider.local().get_calendar(&changed_calendar_url).await.unwrap()
69 .lock().unwrap().add_item(Item::Task(new_task)).await.unwrap();
70
71
72 if provider.sync().await == false {
73 log::warn!("Sync did not complete, see the previous log lines for more info. You can safely start a new sync. The new task may not have been synced.");
74 } else {
75 println!("Done syncing the new task '{}' and the new calendar '{}'", new_task_name, new_calendar_name);
76 }
77 provider.local().save_to_folder().unwrap();
78
79 complete_item_and_sync_again(provider, &changed_calendar_url, &new_url).await;
80}
81
82async fn complete_item_and_sync_again(
83 provider: &mut CalDavProvider,
84 changed_calendar_url: &Url,
85 url_to_complete: &Url)
86{
87 println!("\nNow, we'll mark this last task as completed, and run the sync again.");
88 pause();
89
90 let completion_status = CompletionStatus::Completed(Some(Utc::now()));
91 provider.local().get_calendar(changed_calendar_url).await.unwrap()
92 .lock().unwrap().get_item_by_url_mut(url_to_complete).await.unwrap()
93 .unwrap_task_mut()
94 .set_completion_status(completion_status);
95
96 if provider.sync().await == false {
97 log::warn!("Sync did not complete, see the previous log lines for more info. You can safely start a new sync. The new task may not have been synced.");
98 } else {
99 println!("Done syncing the completed task");
100 }
101 provider.local().save_to_folder().unwrap();
102
103 remove_items_and_sync_again(provider, changed_calendar_url, url_to_complete).await;
104}
105
106async fn remove_items_and_sync_again(
107 provider: &mut CalDavProvider,
108 changed_calendar_url: &Url,
109 id_to_remove: &Url)
110{
111 println!("\nNow, we'll delete this last task, and run the sync again.");
112 pause();
113
114 // Remove the task we had created
115 provider.local().get_calendar(changed_calendar_url).await.unwrap()
116 .lock().unwrap()
117 .mark_for_deletion(id_to_remove).await.unwrap();
118
119 if provider.sync().await == false {
120 log::warn!("Sync did not complete, see the previous log lines for more info. You can safely start a new sync. The new task may not have been synced.");
121 } else {
122 println!("Done syncing the deleted task");
123 }
124 provider.local().save_to_folder().unwrap();
125
126 println!("Done. You can start this example again to see the cache being restored from its current saved state")
127}Source§impl Cache
impl Cache
Sourcepub fn get_calendars_sync(
&self,
) -> Result<HashMap<Url, Arc<Mutex<CachedCalendar>>>, Box<dyn Error>>
pub fn get_calendars_sync( &self, ) -> Result<HashMap<Url, Arc<Mutex<CachedCalendar>>>, Box<dyn Error>>
The non-async version of crate::traits::CalDavSource::get_calendars
Examples found in repository?
37async fn toggle_all_tasks_and_sync_again(provider: &mut CalDavProvider) -> Result<(), Box<dyn Error>> {
38 let mut n_toggled = 0;
39
40 for (_url, cal) in provider.local().get_calendars_sync()?.iter() {
41 for (_url, item) in cal.lock().unwrap().get_items_mut_sync()?.iter_mut() {
42 match item {
43 Item::Task(task) => {
44 match task.completed() {
45 false => task.set_completion_status(CompletionStatus::Completed(Some(Utc::now()))),
46 true => task.set_completion_status(CompletionStatus::Uncompleted),
47 };
48 n_toggled += 1;
49 }
50 Item::Event(_) => {
51 // Not doing anything with calendar events
52 },
53 }
54 }
55 }
56
57 println!("{} items toggled.", n_toggled);
58 println!("Syncing...");
59
60 provider.sync().await;
61
62 println!("Syncing complete.");
63
64 Ok(())
65}Sourcepub fn get_calendar_sync(&self, url: &Url) -> Option<Arc<Mutex<CachedCalendar>>>
pub fn get_calendar_sync(&self, url: &Url) -> Option<Arc<Mutex<CachedCalendar>>>
The non-async version of crate::traits::CalDavSource::get_calendar
Trait Implementations§
Source§impl CalDavSource<CachedCalendar> for Cache
impl CalDavSource<CachedCalendar> for Cache
Source§fn get_calendars<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<HashMap<Url, Arc<Mutex<CachedCalendar>>>, Box<dyn Error>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_calendars<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<HashMap<Url, Arc<Mutex<CachedCalendar>>>, Box<dyn Error>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn get_calendar<'life0, 'life1, 'async_trait>(
&'life0 self,
url: &'life1 Url,
) -> Pin<Box<dyn Future<Output = Option<Arc<Mutex<CachedCalendar>>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_calendar<'life0, 'life1, 'async_trait>(
&'life0 self,
url: &'life1 Url,
) -> Pin<Box<dyn Future<Output = Option<Arc<Mutex<CachedCalendar>>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn create_calendar<'life0, 'async_trait>(
&'life0 mut self,
url: Url,
name: String,
supported_components: SupportedComponents,
color: Option<Color>,
) -> Pin<Box<dyn Future<Output = Result<Arc<Mutex<CachedCalendar>>, Box<dyn Error>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn create_calendar<'life0, 'async_trait>(
&'life0 mut self,
url: Url,
name: String,
supported_components: SupportedComponents,
color: Option<Color>,
) -> Pin<Box<dyn Future<Output = Result<Arc<Mutex<CachedCalendar>>, Box<dyn Error>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Auto Trait Implementations§
impl Freeze for Cache
impl RefUnwindSafe for Cache
impl Send for Cache
impl Sync for Cache
impl Unpin for Cache
impl UnwindSafe for Cache
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more