use crate::error::{FormatError, Result};
use std::collections::HashMap;
pub trait ArtSource {
fn read_window(&self, art_id: i64, offset: u64, buf: &mut [u8]) -> Result<()>;
}
#[derive(Default)]
pub struct MapArtSource {
images: HashMap<i64, Vec<u8>>,
}
impl MapArtSource {
pub fn new(images: impl IntoIterator<Item = (i64, Vec<u8>)>) -> Self {
Self {
images: images.into_iter().collect(),
}
}
}
impl ArtSource for MapArtSource {
fn read_window(&self, art_id: i64, offset: u64, buf: &mut [u8]) -> Result<()> {
let img = self
.images
.get(&art_id)
.ok_or(FormatError::ArtRead { art_id })?;
let start = usize::try_from(offset)
.ok()
.filter(|&s| s <= img.len())
.ok_or(FormatError::ArtRead { art_id })?;
let end = start
.checked_add(buf.len())
.filter(|&e| e <= img.len())
.ok_or(FormatError::ArtRead { art_id })?;
buf.copy_from_slice(&img[start..end]);
Ok(())
}
}