use std::path::{Path, PathBuf};
use crate::target::TargetLayout;
use crate::target_generation::{PngTargetOptions, SvgTargetOptions, TargetGenerationError};
use super::recipe::{Format, RenderRecipe};
#[derive(Debug)]
pub enum ArtifactError {
Io {
path: PathBuf,
source: std::io::Error,
},
Render {
path: PathBuf,
source: TargetGenerationError,
},
}
impl std::fmt::Display for ArtifactError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Io { path, source } => write!(f, "failed to write {}: {source}", path.display()),
Self::Render { path, source } => {
write!(f, "failed to render {}: {source}", path.display())
}
}
}
}
impl std::error::Error for ArtifactError {}
pub fn write_target_artifacts(
target: &TargetLayout,
out_dir: &Path,
basename: &str,
render: &RenderRecipe,
) -> Result<Vec<PathBuf>, ArtifactError> {
std::fs::create_dir_all(out_dir).map_err(|source| ArtifactError::Io {
path: out_dir.to_path_buf(),
source,
})?;
let mut written = Vec::with_capacity(render.formats.len());
for format in &render.formats {
match format {
Format::Json => {
let path = out_dir.join("target_spec.json");
target
.write_json_file(&path)
.map_err(|source| ArtifactError::Io {
path: path.clone(),
source,
})?;
written.push(path);
}
Format::Svg => {
let path = out_dir.join(format!("{basename}.svg"));
target
.write_target_svg(
&path,
&SvgTargetOptions {
margin_mm: render.margin_mm,
include_scale_bar: render.scale_bar,
},
)
.map_err(|source| ArtifactError::Render {
path: path.clone(),
source,
})?;
written.push(path);
}
Format::Png => {
let path = out_dir.join(format!("{basename}.png"));
target
.write_target_png(
&path,
&PngTargetOptions {
dpi: render.dpi,
margin_mm: render.margin_mm,
include_scale_bar: render.scale_bar,
},
)
.map_err(|source| ArtifactError::Render {
path: path.clone(),
source,
})?;
written.push(path);
}
Format::Dxf => {
let path = out_dir.join(format!("{basename}.dxf"));
target
.write_target_dxf(&path)
.map_err(|source| ArtifactError::Render {
path: path.clone(),
source,
})?;
written.push(path);
}
}
}
Ok(written)
}