gamenite/src/io.rs
2022-06-08 12:00:30 -05:00

57 lines
1.6 KiB
Rust

use crate::Board;
use std::io;
use std::io::{ Write, Read, Cursor };
use std::fs::File;
use std::path::Path;
use image::io::Reader as ImageReader;
use image::DynamicImage;
pub fn write_board_to_file(board: &Board, image: Option<&DynamicImage>, path: &Path) -> io::Result<()> {
let file = File::create(path)?;
let mut ar = zip::ZipWriter::new(file);
let options = zip::write::FileOptions::default();
ar.start_file("graph.json", options)?;
ar.write_all(&serde_json::to_vec(board)?)?;
if let Some(image) = image {
ar.start_file("image.png", options)?;
let data = encode_png(image);
ar.write_all(&data)?;
ar.flush()?;
}
ar.finish()?;
Ok(())
}
pub fn read_board_from_file(path: &Path) -> io::Result<(Board, Option<DynamicImage>)> {
let file = File::open(path)?;
let mut ar = zip::ZipArchive::new(file)?;
let json_file = ar.by_name("graph.json")?;
let board = serde_json::from_reader(json_file)?;
let image = ar.by_name("image.png").ok();
if image.is_none() {
return Ok((board, None))
}
let mut image_file = image.unwrap();
let mut buf = Vec::new();
image_file.read_to_end(&mut buf)?;
let image = decode_png(&buf);
Ok((board, Some(image)))
}
pub fn encode_png(image: &DynamicImage) -> Vec<u8> {
let mut cursor = Cursor::new(Vec::new());
image.write_to(&mut cursor, image::ImageOutputFormat::Png).unwrap();
cursor.into_inner()
}
pub fn decode_png(buf: &[u8]) -> DynamicImage {
let cursor = Cursor::new(buf);
let mut reader = ImageReader::new(cursor);
reader.set_format(image::ImageFormat::Png);
reader.decode().unwrap()
}