use crate::{BinaryReader, ComponentExternalKind, ExternalKind, FromReader, Result}; /// Represents the kind of an outer alias in a WebAssembly component. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum ComponentOuterAliasKind { /// The alias is to a core module. CoreModule, /// The alias is to a core type. CoreType, /// The alias is to a component type. Type, /// The alias is to a component. Component, } /// Represents an alias in a WebAssembly component. #[derive(Debug, Clone, Eq, PartialEq)] pub enum ComponentAlias<'a> { /// The alias is to an export of a component instance. InstanceExport { /// The alias kind. kind: ComponentExternalKind, /// The instance index. instance_index: u32, /// The export name. name: &'a str, }, /// The alias is to an export of a module instance. CoreInstanceExport { /// The alias kind. kind: ExternalKind, /// The instance index. instance_index: u32, /// The export name. name: &'a str, }, /// The alias is to an outer item. Outer { /// The alias kind. kind: ComponentOuterAliasKind, /// The outward count, starting at zero for the current component. count: u32, /// The index of the item within the outer component. index: u32, }, } /// Section reader for the component alias section pub type ComponentAliasSectionReader<'a> = crate::SectionLimited<'a, ComponentAlias<'a>>; impl<'a> FromReader<'a> for ComponentAlias<'a> { fn from_reader(reader: &mut BinaryReader<'a>) -> Result { // We don't know what type of alias it is yet, so just read the sort bytes let offset = reader.original_position(); let byte1 = reader.read_u8()?; let byte2 = if byte1 == 0x00 { Some(reader.read_u8()?) } else { None }; Ok(match reader.read_u8()? { 0x00 => ComponentAlias::InstanceExport { kind: ComponentExternalKind::from_bytes(byte1, byte2, offset)?, instance_index: reader.read_var_u32()?, name: reader.read_string()?, }, 0x01 => ComponentAlias::CoreInstanceExport { kind: BinaryReader::external_kind_from_byte( byte2.ok_or_else(|| { BinaryReader::invalid_leading_byte_error( byte1, "core instance export kind", offset, ) })?, offset, )?, instance_index: reader.read_var_u32()?, name: reader.read_string()?, }, 0x02 => ComponentAlias::Outer { kind: component_outer_alias_kind_from_bytes(byte1, byte2, offset)?, count: reader.read_var_u32()?, index: reader.read_var_u32()?, }, x => reader.invalid_leading_byte(x, "alias")?, }) } } fn component_outer_alias_kind_from_bytes( byte1: u8, byte2: Option, offset: usize, ) -> Result { Ok(match byte1 { 0x00 => match byte2.unwrap() { 0x10 => ComponentOuterAliasKind::CoreType, 0x11 => ComponentOuterAliasKind::CoreModule, x => { return Err(BinaryReader::invalid_leading_byte_error( x, "component outer alias kind", offset + 1, )); } }, 0x03 => ComponentOuterAliasKind::Type, 0x04 => ComponentOuterAliasKind::Component, x => { return Err(BinaryReader::invalid_leading_byte_error( x, "component outer alias kind", offset, )); } }) }