Coverage Report

Created: 2026-04-24 07:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wasm-tools/crates/wasm-encoder/src/component/exports.rs
Line
Count
Source
1
use super::{
2
    COMPONENT_SORT, CORE_MODULE_SORT, CORE_SORT, FUNCTION_SORT, INSTANCE_SORT, TYPE_SORT,
3
    VALUE_SORT,
4
};
5
use crate::{ComponentSection, ComponentSectionId, ComponentTypeRef, Encode, encode_section};
6
use alloc::vec::Vec;
7
8
/// Represents the kind of an export from a WebAssembly component.
9
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
10
pub 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
25
impl Encode for ComponentExportKind {
26
276k
    fn encode(&self, sink: &mut Vec<u8>) {
27
276k
        match self {
28
0
            Self::Module => {
29
0
                sink.push(CORE_SORT);
30
0
                sink.push(CORE_MODULE_SORT);
31
0
            }
32
36.5k
            Self::Func => {
33
36.5k
                sink.push(FUNCTION_SORT);
34
36.5k
            }
35
0
            Self::Value => {
36
0
                sink.push(VALUE_SORT);
37
0
            }
38
153k
            Self::Type => {
39
153k
                sink.push(TYPE_SORT);
40
153k
            }
41
66.0k
            Self::Instance => {
42
66.0k
                sink.push(INSTANCE_SORT);
43
66.0k
            }
44
20.7k
            Self::Component => {
45
20.7k
                sink.push(COMPONENT_SORT);
46
20.7k
            }
47
        }
48
276k
    }
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)]
68
pub struct ComponentExportSection {
69
    bytes: Vec<u8>,
70
    num_added: u32,
71
}
72
73
impl ComponentExportSection {
74
    /// Create a new component export section encoder.
75
76.7k
    pub fn new() -> Self {
76
76.7k
        Self::default()
77
76.7k
    }
78
79
    /// The number of exports in the section.
80
0
    pub fn len(&self) -> u32 {
81
0
        self.num_added
82
0
    }
83
84
    /// Determines if the section is empty.
85
0
    pub fn is_empty(&self) -> bool {
86
0
        self.num_added == 0
87
0
    }
88
89
    /// Define an export in the export section.
90
77.0k
    pub fn export(
91
77.0k
        &mut self,
92
77.0k
        name: &str,
93
77.0k
        kind: ComponentExportKind,
94
77.0k
        index: u32,
95
77.0k
        ty: Option<ComponentTypeRef>,
96
77.0k
    ) -> &mut Self {
97
77.0k
        crate::encode_component_export_name(&mut self.bytes, name);
98
77.0k
        kind.encode(&mut self.bytes);
99
77.0k
        index.encode(&mut self.bytes);
100
77.0k
        match ty {
101
784
            Some(ty) => {
102
784
                self.bytes.push(0x01);
103
784
                ty.encode(&mut self.bytes);
104
784
            }
105
76.2k
            None => {
106
76.2k
                self.bytes.push(0x00);
107
76.2k
            }
108
        }
109
77.0k
        self.num_added += 1;
110
77.0k
        self
111
77.0k
    }
112
}
113
114
impl Encode for ComponentExportSection {
115
76.7k
    fn encode(&self, sink: &mut Vec<u8>) {
116
76.7k
        encode_section(sink, self.num_added, &self.bytes);
117
76.7k
    }
118
}
119
120
impl ComponentSection for ComponentExportSection {
121
76.7k
    fn id(&self) -> u8 {
122
76.7k
        ComponentSectionId::Export.into()
123
76.7k
    }
124
}
125
126
/// For more information on this see `encode_component_import_name`.
127
227k
pub(crate) fn encode_component_export_name(bytes: &mut Vec<u8>, name: &str) {
128
227k
    bytes.push(0x00);
129
227k
    name.encode(bytes);
130
227k
}