1use super::{
2 COMPONENT_SORT, CORE_MODULE_SORT, CORE_SORT, FUNCTION_SORT, INSTANCE_SORT, TYPE_SORT,
3 VALUE_SORT,
4};
5use crate::{encode_section, ComponentSection, ComponentSectionId, ComponentTypeRef, Encode};
6
7/// Represents the kind of an export from a WebAssembly component.
8#[derive(Clone, Copy, Debug, Eq, PartialEq)]
9pub enum ComponentExportKind {
10 /// The export is a core module.
11 Module,
12 /// The export is a function.
13 Func,
14 /// The export is a value.
15 Value,
16 /// The export is a type.
17 Type,
18 /// The export is an instance.
19 Instance,
20 /// The export is a component.
21 Component,
22}
23
24impl Encode for ComponentExportKind {
25 fn encode(&self, sink: &mut Vec<u8>) {
26 match self {
27 Self::Module => {
28 sink.push(CORE_SORT);
29 sink.push(CORE_MODULE_SORT);
30 }
31 Self::Func => {
32 sink.push(FUNCTION_SORT);
33 }
34 Self::Value => {
35 sink.push(VALUE_SORT);
36 }
37 Self::Type => {
38 sink.push(TYPE_SORT);
39 }
40 Self::Instance => {
41 sink.push(INSTANCE_SORT);
42 }
43 Self::Component => {
44 sink.push(COMPONENT_SORT);
45 }
46 }
47 }
48}
49
50/// An encoder for the export section of WebAssembly component.
51///
52/// # Example
53///
54/// ```rust
55/// use wasm_encoder::{Component, ComponentExportSection, ComponentExportKind};
56///
57/// // This exports a function named "foo"
58/// let mut exports = ComponentExportSection::new();
59/// exports.export("foo", ComponentExportKind::Func, 0, None);
60///
61/// let mut component = Component::new();
62/// component.section(&exports);
63///
64/// let bytes = component.finish();
65/// ```
66#[derive(Clone, Debug, Default)]
67pub struct ComponentExportSection {
68 bytes: Vec<u8>,
69 num_added: u32,
70}
71
72impl ComponentExportSection {
73 /// Create a new component export section encoder.
74 pub fn new() -> Self {
75 Self::default()
76 }
77
78 /// The number of exports in the section.
79 pub fn len(&self) -> u32 {
80 self.num_added
81 }
82
83 /// Determines if the section is empty.
84 pub fn is_empty(&self) -> bool {
85 self.num_added == 0
86 }
87
88 /// Define an export in the export section.
89 pub fn export(
90 &mut self,
91 name: &str,
92 kind: ComponentExportKind,
93 index: u32,
94 ty: Option<ComponentTypeRef>,
95 ) -> &mut Self {
96 crate::encode_component_export_name(&mut self.bytes, name);
97 kind.encode(&mut self.bytes);
98 index.encode(&mut self.bytes);
99 match ty {
100 Some(ty) => {
101 self.bytes.push(0x01);
102 ty.encode(&mut self.bytes);
103 }
104 None => {
105 self.bytes.push(0x00);
106 }
107 }
108 self.num_added += 1;
109 self
110 }
111}
112
113impl Encode for ComponentExportSection {
114 fn encode(&self, sink: &mut Vec<u8>) {
115 encode_section(sink, self.num_added, &self.bytes);
116 }
117}
118
119impl ComponentSection for ComponentExportSection {
120 fn id(&self) -> u8 {
121 ComponentSectionId::Export.into()
122 }
123}
124
125/// For more information on this see `encode_component_import_name`.
126pub(crate) fn encode_component_export_name(bytes: &mut Vec<u8>, name: &str) {
127 bytes.push(0x00);
128 name.encode(sink:bytes);
129}
130