1use crate::{BinaryReader, ComponentExternalKind, ExternalKind, FromReader, Result};
2
3/// Represents the kind of an outer alias in a WebAssembly component.
4#[derive(Clone, Copy, Debug, Eq, PartialEq)]
5pub enum ComponentOuterAliasKind {
6 /// The alias is to a core module.
7 CoreModule,
8 /// The alias is to a core type.
9 CoreType,
10 /// The alias is to a component type.
11 Type,
12 /// The alias is to a component.
13 Component,
14}
15
16/// Represents an alias in a WebAssembly component.
17#[derive(Debug, Clone, Eq, PartialEq)]
18pub enum ComponentAlias<'a> {
19 /// The alias is to an export of a component instance.
20 InstanceExport {
21 /// The alias kind.
22 kind: ComponentExternalKind,
23 /// The instance index.
24 instance_index: u32,
25 /// The export name.
26 name: &'a str,
27 },
28 /// The alias is to an export of a module instance.
29 CoreInstanceExport {
30 /// The alias kind.
31 kind: ExternalKind,
32 /// The instance index.
33 instance_index: u32,
34 /// The export name.
35 name: &'a str,
36 },
37 /// The alias is to an outer item.
38 Outer {
39 /// The alias kind.
40 kind: ComponentOuterAliasKind,
41 /// The outward count, starting at zero for the current component.
42 count: u32,
43 /// The index of the item within the outer component.
44 index: u32,
45 },
46}
47
48/// Section reader for the component alias section
49pub type ComponentAliasSectionReader<'a> = crate::SectionLimited<'a, ComponentAlias<'a>>;
50
51impl<'a> FromReader<'a> for ComponentAlias<'a> {
52 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
53 // We don't know what type of alias it is yet, so just read the sort bytes
54 let offset = reader.original_position();
55 let byte1 = reader.read_u8()?;
56 let byte2 = if byte1 == 0x00 {
57 Some(reader.read_u8()?)
58 } else {
59 None
60 };
61
62 Ok(match reader.read_u8()? {
63 0x00 => ComponentAlias::InstanceExport {
64 kind: ComponentExternalKind::from_bytes(byte1, byte2, offset)?,
65 instance_index: reader.read_var_u32()?,
66 name: reader.read_string()?,
67 },
68 0x01 => ComponentAlias::CoreInstanceExport {
69 kind: BinaryReader::external_kind_from_byte(
70 byte2.ok_or_else(|| {
71 BinaryReader::invalid_leading_byte_error(
72 byte1,
73 "core instance export kind",
74 offset,
75 )
76 })?,
77 offset,
78 )?,
79 instance_index: reader.read_var_u32()?,
80 name: reader.read_string()?,
81 },
82 0x02 => ComponentAlias::Outer {
83 kind: component_outer_alias_kind_from_bytes(byte1, byte2, offset)?,
84 count: reader.read_var_u32()?,
85 index: reader.read_var_u32()?,
86 },
87 x => reader.invalid_leading_byte(x, "alias")?,
88 })
89 }
90}
91
92fn component_outer_alias_kind_from_bytes(
93 byte1: u8,
94 byte2: Option<u8>,
95 offset: usize,
96) -> Result<ComponentOuterAliasKind> {
97 Ok(match byte1 {
98 0x00 => match byte2.unwrap() {
99 0x10 => ComponentOuterAliasKind::CoreType,
100 0x11 => ComponentOuterAliasKind::CoreModule,
101 x: u8 => {
102 return Err(BinaryReader::invalid_leading_byte_error(
103 byte:x,
104 desc:"component outer alias kind",
105 offset:offset + 1,
106 ))
107 }
108 },
109 0x03 => ComponentOuterAliasKind::Type,
110 0x04 => ComponentOuterAliasKind::Component,
111 x: u8 => {
112 return Err(BinaryReader::invalid_leading_byte_error(
113 byte:x,
114 desc:"component outer alias kind",
115 offset,
116 ))
117 }
118 })
119}
120