1use crate::{
2 encode_section, Encode, GlobalType, MemoryType, Section, SectionId, TableType, TagType,
3 CORE_FUNCTION_SORT, CORE_GLOBAL_SORT, CORE_MEMORY_SORT, CORE_TABLE_SORT, CORE_TAG_SORT,
4};
5
6/// The type of an entity.
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum EntityType {
9 /// A function type.
10 ///
11 /// The value is an index into the types section.
12 Function(u32),
13 /// A table type.
14 Table(TableType),
15 /// A memory type.
16 Memory(MemoryType),
17 /// A global type.
18 Global(GlobalType),
19 /// A tag type.
20 ///
21 /// This variant is used with the exception handling proposal.
22 Tag(TagType),
23}
24
25impl Encode for EntityType {
26 fn encode(&self, sink: &mut Vec<u8>) {
27 match self {
28 Self::Function(i) => {
29 sink.push(CORE_FUNCTION_SORT);
30 i.encode(sink);
31 }
32 Self::Table(t) => {
33 sink.push(CORE_TABLE_SORT);
34 t.encode(sink);
35 }
36 Self::Memory(t) => {
37 sink.push(CORE_MEMORY_SORT);
38 t.encode(sink);
39 }
40 Self::Global(t) => {
41 sink.push(CORE_GLOBAL_SORT);
42 t.encode(sink);
43 }
44 Self::Tag(t) => {
45 sink.push(CORE_TAG_SORT);
46 t.encode(sink);
47 }
48 }
49 }
50}
51
52impl From<TableType> for EntityType {
53 fn from(t: TableType) -> Self {
54 Self::Table(t)
55 }
56}
57
58impl From<MemoryType> for EntityType {
59 fn from(t: MemoryType) -> Self {
60 Self::Memory(t)
61 }
62}
63
64impl From<GlobalType> for EntityType {
65 fn from(t: GlobalType) -> Self {
66 Self::Global(t)
67 }
68}
69
70impl From<TagType> for EntityType {
71 fn from(t: TagType) -> Self {
72 Self::Tag(t)
73 }
74}
75
76/// An encoder for the import section of WebAssembly modules.
77///
78/// # Example
79///
80/// ```rust
81/// use wasm_encoder::{MemoryType, Module, ImportSection};
82///
83/// let mut imports = ImportSection::new();
84/// imports.import(
85/// "env",
86/// "memory",
87/// MemoryType {
88/// minimum: 1,
89/// maximum: None,
90/// memory64: false,
91/// shared: false,
92/// page_size_log2: None,
93/// }
94/// );
95///
96/// let mut module = Module::new();
97/// module.section(&imports);
98///
99/// let bytes = module.finish();
100/// ```
101#[derive(Clone, Debug, Default)]
102pub struct ImportSection {
103 bytes: Vec<u8>,
104 num_added: u32,
105}
106
107impl ImportSection {
108 /// Create a new import section encoder.
109 pub fn new() -> Self {
110 Self::default()
111 }
112
113 /// The number of imports in the section.
114 pub fn len(&self) -> u32 {
115 self.num_added
116 }
117
118 /// Determines if the section is empty.
119 pub fn is_empty(&self) -> bool {
120 self.num_added == 0
121 }
122
123 /// Define an import in the import section.
124 pub fn import(&mut self, module: &str, field: &str, ty: impl Into<EntityType>) -> &mut Self {
125 module.encode(&mut self.bytes);
126 field.encode(&mut self.bytes);
127 ty.into().encode(&mut self.bytes);
128 self.num_added += 1;
129 self
130 }
131}
132
133impl Encode for ImportSection {
134 fn encode(&self, sink: &mut Vec<u8>) {
135 encode_section(sink, self.num_added, &self.bytes);
136 }
137}
138
139impl Section for ImportSection {
140 fn id(&self) -> u8 {
141 SectionId::Import.into()
142 }
143}
144