use alloc::collections::BTreeMap;
use crate::{
daku::{Category, Daku, File, Nucleide, Portal},
parse::Writer,
seal::Seal,
wasm::Write as _,
};
pub trait Write<'a>: Seal {
fn daku(&mut self, daku: &Daku<'_>) -> Option<()>;
fn portals(&mut self, portals: &[Portal]);
fn nucleide(&mut self, subsections: &[Nucleide<'_>]) -> Option<()>;
fn file(&mut self, file: &File<'_>);
fn file_vector(&mut self, files: &[File<'_>]);
fn file_map(&mut self, files: &BTreeMap<u32, File<'_>>);
fn category(&mut self, category: Category);
fn category_vector(&mut self, categories: &[Category]);
}
impl<'a> Write<'a> for Writer<'a> {
fn daku(&mut self, daku: &Daku<'_>) -> Option<()> {
self.portals(daku.portals.as_slice());
if let Some(ref nucleide) = daku.nucleide {
self.nucleide(nucleide.as_slice())?;
}
Some(())
}
fn portals(&mut self, portals: &[Portal]) {
self.integer(portals.len().try_into().unwrap_or(u32::MAX));
for portal in portals.iter().copied() {
self.integer(portal.into());
}
}
fn nucleide(&mut self, subsections: &[Nucleide<'_>]) -> Option<()> {
let mut subsection_min = 0;
for subsection in subsections {
let id = match subsection {
Nucleide::LocalizedNames(_) => 0,
Nucleide::LocalizedDescriptions(_) => 1,
Nucleide::ThemedIcons(_) => 2,
Nucleide::LocalizedAssets(_) => 3,
Nucleide::Tags(_) => 4,
Nucleide::Categories(_) => 5,
Nucleide::Developer(_) => 6,
};
(id >= subsection_min).then_some(())?;
subsection_min = id + 1;
self.u8(id);
match subsection {
Nucleide::LocalizedNames(data) => self.name_map(data),
Nucleide::LocalizedDescriptions(data) => self.name_map(data),
Nucleide::ThemedIcons(data) => self.file_vector(data),
Nucleide::LocalizedAssets(data) => self.file_map(data),
Nucleide::Tags(data) => self.name_vector(data),
Nucleide::Categories(data) => self.category_vector(data),
Nucleide::Developer(data) => self.name(data),
};
}
Some(())
}
fn file(&mut self, file: &File<'_>) {
self.name(&file.path);
self.integer(file.data.len().try_into().unwrap_or(u32::MAX));
self.bytes(&file.data);
}
fn file_vector(&mut self, files: &[File<'_>]) {
self.integer(files.len().try_into().unwrap_or(u32::MAX));
files.iter().for_each(|file| self.file(file));
}
fn file_map(&mut self, files: &BTreeMap<u32, File<'_>>) {
self.integer(files.len().try_into().unwrap_or(u32::MAX));
files.iter().for_each(|(k, v)| {
self.integer(*k);
self.file(v);
});
}
fn category(&mut self, category: Category) {
self.integer(category.into());
}
fn category_vector(&mut self, categories: &[Category]) {
self.integer(categories.len().try_into().unwrap_or(u32::MAX));
categories
.iter()
.for_each(|category| self.category(*category));
}
}