63 lines
1.9 KiB
Rust
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(())
|
|
}
|