use std::collections::HashSet;
use std::path::PathBuf;
use super::super::UnloadPolicy;
use super::Store;
#[derive(Debug, Clone)]
pub struct SyncResult<E> {
pub added: Vec<String>,
pub failed: Vec<(String, E)>,
pub removed: Vec<String>,
pub retained: Vec<String>,
}
impl<E> Default for SyncResult<E> {
fn default() -> Self {
Self {
added: Vec::new(),
failed: Vec::new(),
removed: Vec::new(),
retained: Vec::new(),
}
}
}
impl<T> Store<T>
where
T: Clone + Send + Sync,
{
pub fn sync_with<F, E>(&self, fs_keys: HashSet<String>, mut loader: F) -> SyncResult<E>
where
F: FnMut(&str) -> Result<(T, PathBuf, UnloadPolicy), E>,
{
let mut result = SyncResult::default();
let current_keys: HashSet<String> = self.keys().into_iter().collect();
for key in fs_keys.iter() {
if !current_keys.contains(key) {
match loader(key) {
Ok((value, source, policy)) => {
self.insert(key.clone(), value, source, policy);
result.added.push(key.clone());
}
Err(e) => {
result.failed.push((key.clone(), e));
}
}
}
}
for key in current_keys.iter() {
if !fs_keys.contains(key) {
match self.remove(key) {
Ok(_) => {
result.removed.push(key.clone());
}
Err(_) => {
result.retained.push(key.clone());
}
}
}
}
result
}
}