wasm_encoder/component/
imports.rs1use crate::{
2 ComponentExportKind, ComponentSection, ComponentSectionId, ComponentValType, Encode,
3 encode_section,
4};
5use alloc::borrow::Cow;
6use alloc::string::String;
7use alloc::vec::Vec;
8
9#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
11pub enum TypeBounds {
12 Eq(u32),
14 SubResource,
16}
17
18impl Encode for TypeBounds {
19 fn encode(&self, sink: &mut Vec<u8>) {
20 match self {
21 Self::Eq(i) => {
22 sink.push(0x00);
23 i.encode(sink);
24 }
25 Self::SubResource => sink.push(0x01),
26 }
27 }
28}
29
30#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
32pub enum ComponentTypeRef {
33 Module(u32),
37 Func(u32),
41 Value(ComponentValType),
43 Type(TypeBounds),
45 Instance(u32),
49 Component(u32),
53}
54
55impl ComponentTypeRef {
56 pub fn kind(&self) -> ComponentExportKind {
58 match self {
59 Self::Module(_) => ComponentExportKind::Module,
60 Self::Func(_) => ComponentExportKind::Func,
61 Self::Value(_) => ComponentExportKind::Value,
62 Self::Type(..) => ComponentExportKind::Type,
63 Self::Instance(_) => ComponentExportKind::Instance,
64 Self::Component(_) => ComponentExportKind::Component,
65 }
66 }
67}
68
69impl Encode for ComponentTypeRef {
70 fn encode(&self, sink: &mut Vec<u8>) {
71 self.kind().encode(sink);
72
73 match self {
74 Self::Module(idx) | Self::Func(idx) | Self::Instance(idx) | Self::Component(idx) => {
75 idx.encode(sink);
76 }
77 Self::Value(ty) => ty.encode(sink),
78 Self::Type(bounds) => bounds.encode(sink),
79 }
80 }
81}
82
83#[derive(Clone, Debug, Default)]
114pub struct ComponentImportSection {
115 bytes: Vec<u8>,
116 num_added: u32,
117}
118
119impl ComponentImportSection {
120 pub fn new() -> Self {
122 Self::default()
123 }
124
125 pub fn len(&self) -> u32 {
127 self.num_added
128 }
129
130 pub fn is_empty(&self) -> bool {
132 self.num_added == 0
133 }
134
135 pub fn import<'a>(
137 &mut self,
138 name: impl Into<ComponentExternName<'a>>,
139 ty: ComponentTypeRef,
140 ) -> &mut Self {
141 name.into().encode(&mut self.bytes);
142 ty.encode(&mut self.bytes);
143 self.num_added += 1;
144 self
145 }
146}
147
148impl Encode for ComponentImportSection {
149 fn encode(&self, sink: &mut Vec<u8>) {
150 encode_section(sink, self.num_added, &self.bytes);
151 }
152}
153
154impl ComponentSection for ComponentImportSection {
155 fn id(&self) -> u8 {
156 ComponentSectionId::Import.into()
157 }
158}
159
160#[derive(Debug, Clone)]
162pub struct ComponentExternName<'a> {
163 pub name: Cow<'a, str>,
165 pub implements: Option<Cow<'a, str>>,
168 pub version_suffix: Option<Cow<'a, str>>,
171 pub external_id: Option<Cow<'a, str>>,
174}
175
176impl Encode for ComponentExternName<'_> {
177 fn encode(&self, bytes: &mut Vec<u8>) {
178 let mut options = Vec::new();
179
180 let ComponentExternName {
181 name: _,
182 implements,
183 version_suffix,
184 external_id,
185 } = self;
186
187 if let Some(s) = implements {
188 options.push((0x00, s.as_bytes()));
189 }
190 if let Some(s) = version_suffix {
191 options.push((0x01, s.as_bytes()));
192 }
193 if let Some(s) = external_id {
194 options.push((0x02, s.as_bytes()));
195 }
196
197 if options.is_empty() {
198 bytes.push(0x00);
214 } else {
215 bytes.push(0x02);
216 }
217
218 self.name.encode(bytes);
219
220 if !options.is_empty() {
221 options.len().encode(bytes);
222 for (kind, val) in options {
223 bytes.push(kind);
224 val.encode(bytes);
225 }
226 }
227 }
228}
229
230impl<'a> From<&'a str> for ComponentExternName<'a> {
231 fn from(name: &'a str) -> Self {
232 ComponentExternName {
233 name: Cow::Borrowed(name),
234 implements: None,
235 external_id: None,
236 version_suffix: None,
237 }
238 }
239}
240
241impl<'a> From<&'a String> for ComponentExternName<'a> {
242 fn from(name: &'a String) -> Self {
243 ComponentExternName::from(name.as_str())
244 }
245}
246
247impl<'a> From<String> for ComponentExternName<'a> {
248 fn from(name: String) -> Self {
249 ComponentExternName {
250 name: Cow::Owned(name),
251 implements: None,
252 external_id: None,
253 version_suffix: None,
254 }
255 }
256}
257
258#[cfg(feature = "wasmparser")]
259impl<'a> From<wasmparser::ComponentExternName<'a>> for ComponentExternName<'a> {
260 fn from(name: wasmparser::ComponentExternName<'a>) -> Self {
261 let wasmparser::ComponentExternName {
262 name,
263 implements,
264 external_id,
265 version_suffix,
266 } = name;
267 ComponentExternName {
268 name: name.into(),
269 implements: implements.map(|s| s.into()),
270 external_id: external_id.map(|s| s.into()),
271 version_suffix: version_suffix.map(|s| s.into()),
272 }
273 }
274}