use super::marker::CollectionMarker;
use super::StoreCollection;
use crate::error::Result;
use crate::io_err;
use crate::meta::Meta;
use crate::store::{append_filename, Store, StoreResource};
use itertools::Itertools;
use std::path::{Path, PathBuf};
use std::{fs, mem};
use tauri::Runtime;
impl<R, C> StoreCollection<R, C>
where
R: Runtime,
C: CollectionMarker,
{
pub fn path(&self) -> PathBuf {
self.path.lock().unwrap().clone()
}
pub fn set_path(&self, path: impl AsRef<Path>) -> Result<()> {
let new = path.as_ref().to_path_buf();
if new == *self.path.lock().unwrap() {
return Ok(());
}
fs::create_dir_all(&new)?;
let resources = self
.rids()
.into_iter()
.map(|rid| StoreResource::<R, C>::get(&self.app, rid))
.process_results(|res| res.collect_vec())
.unwrap_or_default();
if resources.is_empty() {
*self.path.lock().unwrap() = new;
return Ok(());
}
{
let stores = resources
.iter()
.map(|resource| resource.inner.lock())
.process_results(|res| res.collect_vec())
.unwrap_or_default();
let mut lock = self.path.lock().unwrap();
let from = mem::replace(&mut *lock, new);
let to = &*lock;
for store in stores {
move_store(&*store, &from, to)?;
}
}
Meta::write(self)?;
Ok(())
}
}
fn move_store<R, C>(store: &Store<R, C>, from: &Path, to: &Path) -> Result<()>
where
R: Runtime,
C: CollectionMarker,
{
let current = append_filename(from, &store.id);
let new = append_filename(to, &store.id);
if new.try_exists()? {
let path = new.display();
return io_err!(AlreadyExists, "file already exists: {path}");
}
fs::copy(¤t, &new)?;
fs::remove_file(¤t)?;
Ok(())
}