use std::{
fs::File,
path::{Path, PathBuf},
process::Command,
str,
};
use image::DynamicImage;
use serde::Deserialize;
#[derive(Deserialize)]
pub struct Aseprite {
pub frames: Vec,
pub meta: Meta,
}
#[derive(Deserialize)]
pub struct Meta {
pub app: String,
pub version: String,
pub image: String,
pub format: String,
pub size: Size,
pub scale: String,
#[serde(rename = "frameTags")]
pub frame_tags: Vec,
}
#[derive(Deserialize)]
pub struct Size {
pub w: u32,
pub h: u32,
}
#[derive(Deserialize, Clone, Copy)]
#[serde(rename_all = "lowercase")]
pub enum Direction {
Forward,
Backward,
Pingpong,
}
#[derive(Deserialize, Clone)]
pub struct FrameTag {
pub name: String,
pub from: u32,
pub to: u32,
pub direction: Direction,
}
#[derive(Deserialize, Clone)]
pub struct Frame {
pub frame: Frame2,
pub trimmed: bool,
}
#[derive(Deserialize, Clone)]
pub struct Frame2 {
pub x: u32,
pub y: u32,
pub w: u32,
pub h: u32,
}
pub fn generate_from_file(filename: &Path) -> (Aseprite, DynamicImage) {
let out_dir = std::env::var("OUT_DIR").expect("Expected OUT_DIR");
let output_filename = Path::new(&out_dir).join(filename.file_name().unwrap());
let image_output = output_filename.with_extension("png");
let json_output = output_filename.with_extension("json");
let command = Command::new("aseprite")
.args([
&PathBuf::from("-b"),
&PathBuf::from(filename),
&"--sheet".into(),
&image_output,
&"--format".into(),
&"json-array".into(),
&"--data".into(),
&json_output,
&"--list-tags".into(),
])
.output()
.expect("Could not run aseprite");
assert!(
command.status.success(),
"Aseprite did not complete successfully : {}",
str::from_utf8(&*command.stdout).unwrap_or("Output contains invalid string")
);
let json: Aseprite = serde_json::from_reader(
File::open(&json_output).expect("The json output from aseprite could not be openned"),
)
.expect("The output from aseprite could not be decoded");
(
json,
image::open(image_output).expect("Image should be readable"),
)
}