2021-08-26 02:46:11 +00:00
|
|
|
#[derive(Debug, thiserror::Error)]
|
2021-08-28 22:15:14 +00:00
|
|
|
pub(crate) enum Exvi2Error {
|
2021-08-26 02:46:11 +00:00
|
|
|
#[error("Failed to interface with exiv2")]
|
|
|
|
IO(#[from] std::io::Error),
|
|
|
|
|
|
|
|
#[error("Identify semaphore is closed")]
|
|
|
|
Closed,
|
|
|
|
|
2021-08-28 22:15:14 +00:00
|
|
|
#[error("Exiv2 command failed")]
|
|
|
|
Status,
|
2021-08-26 02:46:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static MAX_READS: once_cell::sync::OnceCell<tokio::sync::Semaphore> =
|
|
|
|
once_cell::sync::OnceCell::new();
|
|
|
|
|
|
|
|
fn semaphore() -> &'static tokio::sync::Semaphore {
|
2021-08-29 05:05:02 +00:00
|
|
|
MAX_READS.get_or_init(|| tokio::sync::Semaphore::new(num_cpus::get() * 5))
|
2021-08-26 02:46:11 +00:00
|
|
|
}
|
|
|
|
|
2021-08-28 22:15:14 +00:00
|
|
|
pub(crate) async fn clear_metadata<P>(file: P) -> Result<(), Exvi2Error>
|
2021-08-26 02:46:11 +00:00
|
|
|
where
|
|
|
|
P: AsRef<std::path::Path>,
|
|
|
|
{
|
|
|
|
let permit = semaphore().acquire().await?;
|
|
|
|
|
2021-08-28 22:15:14 +00:00
|
|
|
let status = tokio::process::Command::new("exiv2")
|
|
|
|
.arg(&"rm")
|
|
|
|
.arg(&file.as_ref())
|
|
|
|
.spawn()?
|
|
|
|
.wait()
|
2021-08-26 02:46:11 +00:00
|
|
|
.await?;
|
2021-08-28 22:15:14 +00:00
|
|
|
|
2021-08-26 02:46:11 +00:00
|
|
|
drop(permit);
|
|
|
|
|
2021-08-28 22:15:14 +00:00
|
|
|
if !status.success() {
|
|
|
|
return Err(Exvi2Error::Status);
|
2021-08-26 02:46:11 +00:00
|
|
|
}
|
|
|
|
|
2021-08-28 22:15:14 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<tokio::sync::AcquireError> for Exvi2Error {
|
|
|
|
fn from(_: tokio::sync::AcquireError) -> Exvi2Error {
|
|
|
|
Exvi2Error::Closed
|
|
|
|
}
|
|
|
|
}
|