Poor man's generic function to work around passing an async closure

This commit is contained in:
daladim 2021-12-24 14:50:41 +01:00
parent 313f2ed0e9
commit 159b6199fa

View file

@ -6,8 +6,9 @@ use std::error::Error;
use std::collections::HashSet; use std::collections::HashSet;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use url::Url; use std::fmt::{Display, Formatter};
use url::Url;
use itertools::Itertools; use itertools::Itertools;
use crate::traits::{BaseCalendar, CalDavSource, DavCalendar}; use crate::traits::{BaseCalendar, CalDavSource, DavCalendar};
@ -25,6 +26,22 @@ const DOWNLOAD_BATCH_SIZE: usize = 30;
#[cfg(test)] #[cfg(test)]
const DOWNLOAD_BATCH_SIZE: usize = 3; const DOWNLOAD_BATCH_SIZE: usize = 3;
// I am too lazy to actually make `fetch_and_apply` generic over an async closure.
// Let's work around by passing an enum, so that `fetch_and_apply` will know what to do
enum BatchDownloadType {
RemoteAdditions,
RemoteChanges,
}
impl Display for BatchDownloadType {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
match self {
Self::RemoteAdditions => write!(f, "remote additions"),
Self::RemoteChanges => write!(f, "remote changes"),
}
}
}
/// A data source that combines two `CalDavSource`s, which is able to sync both sources. /// A data source that combines two `CalDavSource`s, which is able to sync both sources.
/// ///
@ -405,23 +422,24 @@ where
cal_name: &str cal_name: &str
) { ) {
for batch in remote_additions.drain().chunks(DOWNLOAD_BATCH_SIZE).into_iter() { for batch in remote_additions.drain().chunks(DOWNLOAD_BATCH_SIZE).into_iter() {
Self::apply_some_remote_additions(batch, cal_local, cal_remote, progress, cal_name).await; Self::fetch_batch_and_apply(BatchDownloadType::RemoteAdditions, batch, cal_local, cal_remote, progress, cal_name).await;
} }
} }
async fn apply_some_remote_additions<I: Iterator<Item = Url>>( async fn fetch_batch_and_apply<I: Iterator<Item = Url>>(
batch_type: BatchDownloadType,
remote_additions: I, remote_additions: I,
cal_local: &mut T, cal_local: &mut T,
cal_remote: &mut U, cal_remote: &mut U,
progress: &mut SyncProgress, progress: &mut SyncProgress,
cal_name: &str cal_name: &str
) { ) {
progress.debug(&format!("> Applying a batch of remote additions locally") /* too bad Chunks does not implement ExactSizeIterator, that could provide useful debug info. See https://github.com/rust-itertools/itertools/issues/171 */); progress.debug(&format!("> Applying a batch of {} locally", batch_type) /* too bad Chunks does not implement ExactSizeIterator, that could provide useful debug info. See https://github.com/rust-itertools/itertools/issues/171 */);
let list_of_additions: Vec<Url> = remote_additions.map(|url| url.clone()).collect(); let list_of_additions: Vec<Url> = remote_additions.map(|url| url.clone()).collect();
match cal_remote.get_items_by_url(&list_of_additions).await { match cal_remote.get_items_by_url(&list_of_additions).await {
Err(err) => { Err(err) => {
progress.warn(&format!("Unable to get a batch of items {:?}: {}. Skipping them.", list_of_additions, err)); progress.warn(&format!("Unable to get the batch of {} {:?}: {}. Skipping them.", batch_type, list_of_additions, err));
}, },
Ok(items) => { Ok(items) => {
for item in items { for item in items {