use miette::IntoDiagnostic;
use rattler_digest::{HashingReader, Sha256, Sha256Hash};
use std::fs::File;
use std::io::{self, BufReader, Read, copy};
use std::path::Path;
use tokio::io::AsyncRead;
use tokio_util::io::SyncIoBridge;
#[inline(always)]
pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
match remove_dir_all::remove_dir_all(path) {
Ok(_) => Ok(()),
Err(err) if err.kind() == io::ErrorKind::NotFound => Ok(()),
Err(err) => Err(err),
}
}
#[inline(always)]
pub fn empty_dir<P: AsRef<Path> + ?Sized>(path: &P) -> io::Result<()> {
match remove_dir_all::remove_dir_contents(path) {
Ok(_) => Ok(()),
Err(err) if err.kind() == io::ErrorKind::NotFound => Ok(()),
Err(err) => Err(err),
}
}
fn save_file_sync(stream: impl Read, destination: &Path) -> miette::Result<Sha256Hash> {
std::fs::create_dir_all(destination.parent().expect("invalid destination"))
.into_diagnostic()?;
let mut file = File::create(destination).into_diagnostic()?;
let mut sha256_reader = HashingReader::<_, Sha256>::new(BufReader::new(stream));
copy(&mut sha256_reader, &mut file).into_diagnostic()?;
let (_, sha256) = sha256_reader.finalize();
Ok(sha256)
}
fn compute_file_sha256_sync(path: &Path) -> miette::Result<Sha256Hash> {
let file = File::open(path).into_diagnostic()?;
let mut sha256_reader = HashingReader::<_, Sha256>::new(BufReader::new(file));
copy(&mut sha256_reader, &mut io::sink()).into_diagnostic()?;
let (_, sha256) = sha256_reader.finalize();
Ok(sha256)
}
pub async fn save_file(
reader: impl AsyncRead + Send + 'static,
destination: &Path,
) -> miette::Result<Sha256Hash> {
let reader = SyncIoBridge::new(Box::pin(reader));
let destination = destination.to_owned();
match tokio::task::spawn_blocking(move || save_file_sync(reader, &destination)).await {
Ok(result) => result,
Err(err) => Err(err).into_diagnostic(),
}
}
pub async fn compute_file_sha256(path: &Path) -> miette::Result<Sha256Hash> {
let path = path.to_owned();
match tokio::task::spawn_blocking(move || compute_file_sha256_sync(&path)).await {
Ok(result) => result,
Err(err) => Err(err).into_diagnostic(),
}
}