use alloc::{collections::BTreeMap, vec::Vec};
use crate::{
daku::{Category, Daku, File, Nucleide, Portal},
parse::Reader,
seal::Seal,
wasm::Read as _,
};
pub trait Read<'a>: Seal {
fn daku(&mut self) -> Option<Daku<'a>>;
fn portals(&mut self) -> Option<Vec<Portal>>;
fn nucleide(&mut self) -> Option<Vec<Nucleide<'a>>>;
fn file(&mut self) -> Option<File<'a>>;
fn file_vector(&mut self) -> Option<Vec<File<'a>>>;
fn file_map(&mut self) -> Option<BTreeMap<u32, File<'a>>>;
fn category(&mut self) -> Option<Category>;
fn category_vector(&mut self) -> Option<Vec<Category>>;
}
impl<'a> Read<'a> for Reader<'a> {
fn daku(&mut self) -> Option<Daku<'a>> {
Some(Daku {
portals: self.portals()?,
nucleide: if self.end().is_none() {
Some(self.nucleide()?)
} else {
None
},
})
}
fn portals(&mut self) -> Option<Vec<Portal>> {
let size = self.integer()?.try_into().ok()?;
(0..size).map(|_| self.integer()?.try_into().ok()).collect()
}
fn nucleide(&mut self) -> Option<Vec<Nucleide<'a>>> {
let mut subsections = Vec::new();
let mut subsection_min = 0;
while self.end().is_none() {
let (subsection, mut reader) = self.subsection()?;
(subsection >= subsection_min).then_some(())?;
subsections.push(match subsection {
0 => Nucleide::LocalizedNames(reader.name_map()?),
1 => Nucleide::LocalizedDescriptions(reader.name_map()?),
2 => Nucleide::ThemedIcons(reader.file_vector()?),
3 => Nucleide::LocalizedAssets(reader.file_map()?),
4 => Nucleide::Tags(reader.name_vector()?),
5 => Nucleide::Categories(reader.category_vector()?),
6 => Nucleide::Developer(reader.name()?),
_ => return None,
});
reader.end()?;
subsection_min = subsection + 1;
}
Some(subsections)
}
fn file(&mut self) -> Option<File<'a>> {
Some(File {
path: self.name()?,
data: {
let len = self.integer()?.try_into().ok()?;
self.bytes(len)?.into()
},
})
}
fn file_vector(&mut self) -> Option<Vec<File<'a>>> {
(0..self.integer()?).map(|_| self.file()).collect()
}
fn file_map(&mut self) -> Option<BTreeMap<u32, File<'a>>> {
let mut file_map = BTreeMap::new();
for _ in 0..self.integer()? {
file_map.insert(self.integer()?, self.file()?);
}
Some(file_map)
}
fn category(&mut self) -> Option<Category> {
self.integer()?.try_into().ok()
}
fn category_vector(&mut self) -> Option<Vec<Category>> {
(0..self.integer()?).map(|_| self.category()).collect()
}
}