use std::path::PathBuf;
use tempfile::Builder;
use crate::{Error, Job, Options, Result, conversion_map};
pub fn run(
from: &str,
to: &str,
entry: conversion_map::Entry,
job: &Job,
) -> Result<()> {
if let Some(func) = entry.direct {
return func(job);
}
let mut current_input: PathBuf = job.input.to_path_buf();
let mut current_from: String = from.to_string();
let mut temps: Vec<tempfile::NamedTempFile> = Vec::new();
let hops: Vec<&str> = entry
.intermediates
.iter()
.copied()
.chain(std::iter::once(to))
.collect();
let steps = hops.len();
let hop_opts = Options {
force: true,
split: false,
};
for (i, next_ext) in hops.iter().enumerate() {
let is_last = i + 1 == steps;
let hop_entry = conversion_map::lookup(¤t_from, next_ext).ok_or(
Error::Unsupported {
from: current_from.clone(),
to: (*next_ext).to_string(),
},
)?;
let next_output: PathBuf = if is_last {
job.output.to_path_buf()
} else {
let tmp = Builder::new()
.prefix("univert-")
.suffix(&format!(".{next_ext}"))
.tempfile()?;
let path = tmp.path().to_path_buf();
temps.push(tmp);
path
};
let hop_job = Job {
input: ¤t_input,
output: &next_output,
options: if is_last { job.options } else { &hop_opts },
};
let func = hop_entry.direct.ok_or_else(|| Error::Unsupported {
from: current_from.clone(),
to: (*next_ext).to_string(),
})?;
func(&hop_job)?;
current_input = next_output;
current_from = (*next_ext).to_string();
}
Ok(())
}