use crate::{
BinaryReader, BinaryReaderError, FromReader, Result, SectionLimited, Subsection, Subsections,
};
use core::ops::Range;
pub type NameMap<'a> = SectionLimited<'a, Naming<'a>>;
#[derive(Debug, Copy, Clone)]
pub struct Naming<'a> {
pub index: u32,
pub name: &'a str,
}
impl<'a> FromReader<'a> for Naming<'a> {
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
let index = reader.read_var_u32()?;
let name = reader.read_unlimited_string()?;
Ok(Naming { index, name })
}
}
pub type IndirectNameMap<'a> = SectionLimited<'a, IndirectNaming<'a>>;
#[derive(Debug, Clone)]
pub struct IndirectNaming<'a> {
pub index: u32,
pub names: NameMap<'a>,
}
impl<'a> FromReader<'a> for IndirectNaming<'a> {
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
let index = reader.read_var_u32()?;
let names = reader.skip(|reader| {
let count = reader.read_var_u32()?;
for _ in 0..count {
reader.read_var_u32()?;
reader.skip_string()?;
}
Ok(())
})?;
Ok(IndirectNaming {
index,
names: NameMap::new(names)?,
})
}
}
#[derive(Clone)]
pub enum Name<'a> {
Module {
name: &'a str,
name_range: Range<usize>,
},
Function(NameMap<'a>),
Local(IndirectNameMap<'a>),
Label(IndirectNameMap<'a>),
Type(NameMap<'a>),
Table(NameMap<'a>),
Memory(NameMap<'a>),
Global(NameMap<'a>),
Element(NameMap<'a>),
Data(NameMap<'a>),
Field(IndirectNameMap<'a>),
Tag(NameMap<'a>),
Unknown {
ty: u8,
data: &'a [u8],
range: Range<usize>,
},
}
pub type NameSectionReader<'a> = Subsections<'a, Name<'a>>;
impl<'a> Subsection<'a> for Name<'a> {
fn from_reader(id: u8, mut reader: BinaryReader<'a>) -> Result<Self> {
let data = reader.remaining_buffer();
let offset = reader.original_position();
Ok(match id {
0 => {
let name = reader.read_string()?;
if !reader.eof() {
return Err(BinaryReaderError::new(
"trailing data at the end of a name",
reader.original_position(),
));
}
Name::Module {
name,
name_range: offset..reader.original_position(),
}
}
1 => Name::Function(NameMap::new(reader)?),
2 => Name::Local(IndirectNameMap::new(reader)?),
3 => Name::Label(IndirectNameMap::new(reader)?),
4 => Name::Type(NameMap::new(reader)?),
5 => Name::Table(NameMap::new(reader)?),
6 => Name::Memory(NameMap::new(reader)?),
7 => Name::Global(NameMap::new(reader)?),
8 => Name::Element(NameMap::new(reader)?),
9 => Name::Data(NameMap::new(reader)?),
10 => Name::Field(IndirectNameMap::new(reader)?),
11 => Name::Tag(NameMap::new(reader)?),
ty => Name::Unknown {
ty,
data,
range: offset..offset + data.len(),
},
})
}
}