81 lines
2.0 KiB
Rust
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)
|
|
}
|
|
}
|