cathode/ray_format/src/model.rs

81 lines
2.0 KiB
Rust

use anyhow::Result;
use std::{
collections::{hash_map::Keys, HashMap},
fs,
path::Path,
};
use crate::archive::Archive;
#[derive(Default, Clone, Debug)]
pub struct Ray {
frames: [Vec<u8>; 4],
extras: HashMap<String, Vec<u8>>,
meta: HashMap<String, String>,
}
impl Ray {
pub fn get_meta_keys(&self) -> Keys<String, String> {
self.meta.keys()
}
pub fn get_meta_value(&self, key: &str) -> Option<&String> {
self.meta.get(key)
}
pub fn get_frame(&self, index: usize) -> Option<&Vec<u8>> {
self.frames.get(index)
}
pub fn set_frame(&mut self, index: usize, data: Vec<u8>) -> bool {
if let Some(i) = self.frames.get_mut(index) {
*i = data;
true
} else {
false
}
}
pub fn add_meta(&mut self, key: String, value: String) -> bool {
self.meta.insert(key, value).is_none()
}
pub fn save(&self, path: &Path) -> Result<()> {
let mut archive = Archive::new();
for (i, f) in self.frames.iter().enumerate() {
if f.len() > 0 {
archive.add_file(&format!("{}", i), f)?
}
}
for (n, f) in self.extras.iter() {
archive.add_file(&n, f)?;
}
let meta = serde_json::to_string(&self.meta)?;
archive.add_file("meta.json", meta.as_bytes())?;
fs::write(path, archive.buffer())?;
Ok(())
}
pub fn load(path: impl AsRef<Path>) -> Result<Self> {
let mut ray = Self::default();
let data = fs::read(path.as_ref())?;
let archive = Archive::open(&data);
for i in 0..4 {
if let Ok(buf) = archive.get_file(&i.to_string()) {
ray.set_frame(i as usize, buf);
}
}
if let Ok(buf) = archive.get_file("meta.json") {
let meta: HashMap<String, String> = serde_json::from_slice(&buf)?;
ray.meta = meta;
}
Ok(ray)
}
}