vagabond/src/operations/cp.rs

63 lines
1.9 KiB
Rust

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<P, Q>(source_path: P, target_path: Q) -> Result<(), EntryWriteError>
where
P: AsRef<Path>,
Q: AsRef<Path>,
{
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<P, Q>(source_path: P, target_path: Q) -> Result<(), EntryWriteError>
where
P: AsRef<Path>,
Q: AsRef<Path>,
{
std::fs::copy(source_path, target_path)?;
Ok(())
}
fn copy_directory<P, Q>(source_path: P, target_path: Q) -> Result<(), EntryWriteError>
where
P: AsRef<Path>,
Q: AsRef<Path>,
{
for entry in list_directory(&source_path)? {
let target_path = target_path.as_ref().join(entry.name);
copy(entry.path, &target_path)?;
}
Ok(())
}