use xo65::{file::File, Xo65};
use crate::util::fmt_maybe_string;
pub trait Xo65Query<'data> {
fn get_file(&self, idx: u32) -> Option<&File>;
fn fmt_file(&self, idx: u32) -> FmtXo65File<'_, 'data>;
#[allow(dead_code)]
fn get_string(&self, idx: u32) -> Option<&'data [u8]>;
fn fmt_string(&self, idx: u32) -> FmtXo65String<'_, 'data>;
}
impl<'data> Xo65Query<'data> for Xo65<'data> {
fn get_file(&self, idx: u32) -> Option<&File> {
self.file_table().get(idx as usize)
}
fn fmt_file(&self, idx: u32) -> FmtXo65File<'_, 'data> {
FmtXo65File { obj: self, idx }
}
fn get_string(&self, idx: u32) -> Option<&'data [u8]> {
self.string_table().get(idx as usize)
}
fn fmt_string(&self, idx: u32) -> FmtXo65String<'_, 'data> {
FmtXo65String { obj: self, idx }
}
}
#[derive(Debug)]
pub struct FmtXo65File<'a, 'data> {
obj: &'a Xo65<'data>,
idx: u32,
}
impl std::fmt::Display for FmtXo65File<'_, '_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(file) = self.obj.get_file(self.idx) {
self.obj.fmt_string(file.name()).fmt(f)
} else {
write!(f, "{} (file index OUT OF RANGE)", self.idx)
}
}
}
#[derive(Debug)]
pub struct FmtXo65String<'a, 'data> {
obj: &'a Xo65<'data>,
idx: u32,
}
impl std::fmt::Display for FmtXo65String<'_, '_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.idx == 0 {
write!(f, "<None>")
} else if let Some(s) = self.obj.string_table().get(self.idx as usize) {
fmt_maybe_string(s).fmt(f)
} else {
write!(f, "{} (string index OUT OF RANGE)", self.idx)
}
}
}