use std::path::{Path, PathBuf};
pub fn copy_file<'a>(
from: &'a Path,
to: &'a Path,
) -> std::io::Result<Result<PathBuf, &'static str>> {
if let Some(file_name) = from.file_name() {
if let Err(e) = std::fs::copy(
from,
format!("{}/{}", to.display(), file_name.to_string_lossy()),
) {
return Err(e);
}
return Ok(Ok(from.to_path_buf()));
}
Ok(Err(
"Path did not contain a file or directory name, and instead ended in '..'",
))
}
pub fn copy_files<'a>(
from: Vec<&'a Path>,
to: &'a Path,
) -> std::io::Result<Vec<Result<PathBuf, &'static str>>> {
let mut list = Vec::new();
for pb in from {
match copy_file(&pb, to) {
Ok(r) => match r {
Ok(p) => list.push(Ok(p)),
Err(e) => list.push(Err(e)),
},
Err(e) => return Err(e),
}
}
Ok(list)
}
pub struct CopyOperation {
pub paths: Vec<PathBuf>,
pub results: Vec<Result<PathBuf, &'static str>>,
}
impl CopyOperation {
pub fn new(paths: Vec<PathBuf>) -> Self {
Self {
paths,
results: Vec::new(),
}
}
pub fn only(path: PathBuf) -> Self {
Self {
paths: vec![path],
results: Vec::new(),
}
}
pub fn copy_to(&mut self, dest: &Path) -> std::io::Result<()> {
match copy_files(self.paths.iter().map(|pb| pb.as_path()).collect(), dest) {
Ok(v) => {
self.results = v;
Ok(())
}
Err(e) => Err(e),
}
}
}
impl From<Vec<&Path>> for CopyOperation {
fn from(vec: Vec<&Path>) -> Self {
Self {
paths: vec.iter().map(|p| p.into()).collect(),
results: Vec::new(),
}
}
}
impl From<&Path> for CopyOperation {
fn from(path: &Path) -> Self {
CopyOperation::only(path.into())
}
}
#[cfg(test)]
mod tests {}