use crate::make_parent_directory; use crate::{get_entry, get_optional_entry, list_directory}; use crate::{EntryType, EntryWriteError}; use std::path::Path; pub fn copy(source_path: P, target_path: Q) -> Result<(), EntryWriteError> where P: AsRef, Q: AsRef, { let source = get_entry(&source_path)?; let target = get_optional_entry(&target_path)?; let target_type = target.and_then(|e| Some(e.entry_type)); match (source.entry_type, target_type) { (EntryType::File, Some(EntryType::File)) => { copy_file(source_path, target_path)?; } (EntryType::File, Some(EntryType::Directory)) => { let target_path = target_path.as_ref().join(source.name); copy_file(source_path, target_path)?; } (EntryType::File, None) => { make_parent_directory(&target_path)?; copy_file(source_path, target_path)?; } (EntryType::Directory, Some(EntryType::File)) => { std::fs::remove_file(&target_path)?; copy_directory(&source_path, &target_path)?; } (EntryType::Directory, Some(EntryType::Directory)) => { let target_path = target_path.as_ref().join(source.name); copy_directory(source_path, target_path)?; } (EntryType::Directory, None) => { make_parent_directory(&target_path)?; copy_directory(source_path, target_path)?; } } Ok(()) } fn copy_file(source_path: P, target_path: Q) -> Result<(), EntryWriteError> where P: AsRef, Q: AsRef, { std::fs::copy(source_path, target_path)?; Ok(()) } fn copy_directory(source_path: P, target_path: Q) -> Result<(), EntryWriteError> where P: AsRef, Q: AsRef, { for entry in list_directory(&source_path)? { let target_path = target_path.as_ref().join(entry.name); copy(entry.path, &target_path)?; } Ok(()) }