Skip to main content

wasm_encoder/component/
exports.rs

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