Fixed a SyncStatus inconsistency

This commit is contained in:
daladim 2021-04-03 18:32:59 +02:00
parent 841d14807b
commit 3d9adcec08
6 changed files with 90 additions and 29 deletions

View file

@ -17,10 +17,43 @@ pub struct CachedCalendar {
name: String,
id: CalendarId,
supported_components: SupportedComponents,
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
is_mocking_remote_calendar: bool,
items: HashMap<ItemId, Item>,
}
impl CachedCalendar {
/// Activate the "mocking remote calendar" feature (i.e. ignore sync statuses, since this is what an actual CalDAV sever would do)
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
pub fn set_is_mocking_remote_calendar(&mut self) {
self.is_mocking_remote_calendar = true;
}
/// Add an item
async fn regular_add_item(&mut self, item: Item) -> Result<SyncStatus, Box<dyn Error>> {
// TODO: here (and in the remote version, display an errror in case we overwrite something?)
let ss_clone = item.sync_status().clone();
log::debug!("Adding an item with {:?}", ss_clone);
self.items.insert(item.id().clone(), item);
Ok(ss_clone)
}
/// Add an item, but force a "synced" SyncStatus. This is the typical behaviour on a remote calendar
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
async fn add_item_force_synced(&mut self, mut item: Item) -> Result<SyncStatus, Box<dyn Error>> {
log::debug!("Adding an item, but forces a synced SyncStatus");
match item.sync_status() {
SyncStatus::Synced(_) => (),
_ => item.set_sync_status(SyncStatus::random_synced()),
};
let ss_clone = item.sync_status().clone();
self.items.insert(item.id().clone(), item);
Ok(ss_clone)
}
}
#[async_trait]
impl BaseCalendar for CachedCalendar {
fn name(&self) -> &str {
@ -35,10 +68,17 @@ impl BaseCalendar for CachedCalendar {
self.supported_components
}
async fn add_item(&mut self, item: Item) -> Result<(), Box<dyn Error>> {
// TODO: here (and in the remote version, display an errror in case we overwrite something?)
self.items.insert(item.id().clone(), item);
Ok(())
#[cfg(not(feature = "local_calendar_mocks_remote_calendars"))]
async fn add_item(&mut self, item: Item) -> Result<SyncStatus, Box<dyn Error>> {
self.regular_add_item(item).await
}
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
async fn add_item(&mut self, item: Item) -> Result<SyncStatus, Box<dyn Error>> {
if self.is_mocking_remote_calendar {
self.add_item_force_synced(item).await
} else {
self.regular_add_item(item).await
}
}
}
@ -47,6 +87,8 @@ impl CompleteCalendar for CachedCalendar {
fn new(name: String, id: CalendarId, supported_components: SupportedComponents) -> Self {
Self {
name, id, supported_components,
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
is_mocking_remote_calendar: false,
items: HashMap::new(),
}
}

View file

@ -58,8 +58,8 @@ impl BaseCalendar for RemoteCalendar {
}
/// Add an item into this calendar
async fn add_item(&mut self, _item: Item) -> Result<(), Box<dyn Error>> {
Err("Not implemented".into())
async fn add_item(&mut self, _item: Item) -> Result<SyncStatus, Box<dyn Error>> {
todo!()
}
}

View file

@ -247,14 +247,18 @@ where
for id_add in local_additions {
log::debug!("> Pushing local addition {} to the server", id_add);
match cal_local.get_item_by_id_ref(&id_add).await {
match cal_local.get_item_by_id_mut(&id_add).await {
None => {
log::error!("Inconsistency: created item {} has been marked for upload but is locally missing", id_add);
continue;
},
Some(item) => {
if let Err(err) = cal_remote.add_item(item.clone()).await {
log::error!("Unable to add item {} to remote calendar: {}", id_add, err);
match cal_remote.add_item(item.clone()).await {
Err(err) => log::error!("Unable to add item {} to remote calendar: {}", id_add, err),
Ok(new_ss) => {
// Update local sync status
item.set_sync_status(new_ss);
},
}
},
};
@ -262,7 +266,7 @@ where
for id_change in local_changes {
log::debug!("> Pushing local change {} to the server", id_change);
match cal_local.get_item_by_id_ref(&id_change).await {
match cal_local.get_item_by_id_mut(&id_change).await {
None => {
log::error!("Inconsistency: modified item {} has been marked for upload but is locally missing", id_change);
continue;
@ -271,8 +275,12 @@ where
if let Err(err) = cal_remote.delete_item(&id_change).await {
log::error!("Unable to delete item {} from remote calendar: {}", id_change, err);
}
if let Err(err) = cal_remote.add_item(item.clone()).await {
log::error!("Unable to add item {} to remote calendar: {}", id_change, err);
match cal_remote.add_item(item.clone()).await {
Err(err) => log::error!("Unable to add item {} to remote calendar: {}", id_change, err),
Ok(new_ss) => {
// Update local sync status
item.set_sync_status(new_ss);
},
}
}
};

View file

@ -4,6 +4,7 @@ use std::sync::{Arc, Mutex};
use async_trait::async_trait;
use crate::SyncStatus;
use crate::item::Item;
use crate::item::ItemId;
use crate::item::VersionTag;
@ -34,8 +35,10 @@ pub trait BaseCalendar {
/// Returns the supported kinds of components for this calendar
fn supported_components(&self) -> crate::calendar::SupportedComponents;
/// Add an item into this calendar
async fn add_item(&mut self, item: Item) -> Result<(), Box<dyn Error>>;
/// Add an item into this calendar, and return its new sync status.
/// For local calendars, the sync status is not modified.
/// For remote calendars, the sync status is updated by the server
async fn add_item(&mut self, item: Item) -> Result<SyncStatus, Box<dyn Error>>;
/// Returns whether this calDAV calendar supports to-do items
fn supports_todo(&self) -> bool {

View file

@ -106,9 +106,10 @@ pub fn print_task(item: &Item) {
status += " ";
}
match task.sync_status() {
SyncStatus::NotSynced => { status += " "; },
SyncStatus::Synced(_) => { status += "="; },
SyncStatus::LocallyModified(_) => { status += "~"; },
SyncStatus::LocallyDeleted(_) => { status += "x"; },
_ => (),
}
println!(" {} {}\t{}", status, task.name(), task.id());
},