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