use std::fs::File;
use std::io::BufWriter;
use std::path::Path;
use crate::core::{Error, Result};
use super::stage::{Staged, ensure_new};
pub(crate) fn create_new<T>(
path: &Path,
write: impl FnOnce(&mut BufWriter<File>) -> Result<T>,
) -> Result<T> {
let (staged, value) = Staged::new(path, write)?;
staged.install()?;
Ok(value)
}
pub(crate) fn create_pair<T, U>(
first_path: &Path,
first_write: impl FnOnce(&mut BufWriter<File>) -> Result<T>,
second_path: &Path,
second_write: impl FnOnce(&mut BufWriter<File>) -> Result<U>,
) -> Result<(T, U)> {
if first_path == second_path {
return Err(Error::new("E_USAGE", "paired outputs need distinct paths"));
}
ensure_new(first_path)?;
ensure_new(second_path)?;
let (first, first_value) = Staged::new(first_path, first_write)?;
let (mut second, second_value) = Staged::new(second_path, second_write)?;
first.install()?;
second.install().map_err(|error| {
let recovery = second.retain_for_recovery().map_or_else(
|| "the staged second output is unavailable".to_owned(),
|path| format!("completed second output retained at {}", path.display()),
);
Error::new(
error.code,
format!(
"{} was created, but {} could not be installed: {}; {recovery}",
first_path.display(),
second_path.display(),
error.message
),
)
})?;
Ok((first_value, second_value))
}