wasm_encoder/core/
imports.rs

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