Skip to main content

wasm_encoder/component/
types.rs

1use super::CORE_TYPE_SORT;
2use crate::{
3    Alias, ComponentExportKind, ComponentExternName, ComponentOuterAliasKind, ComponentSection,
4    ComponentSectionId, ComponentTypeRef, CoreTypeEncoder, Encode, EntityType, ValType,
5    encode_section,
6};
7use alloc::vec::Vec;
8
9/// Represents the type of a core module.
10#[derive(Debug, Clone, Default)]
11pub struct ModuleType {
12    bytes: Vec<u8>,
13    num_added: u32,
14    types_added: u32,
15}
16
17impl ModuleType {
18    /// Creates a new core module type.
19    pub fn new() -> Self {
20        Self::default()
21    }
22
23    /// Defines an import in this module type.
24    pub fn import(&mut self, module: &str, name: &str, ty: EntityType) -> &mut Self {
25        self.bytes.push(0x00);
26        module.encode(&mut self.bytes);
27        name.encode(&mut self.bytes);
28        ty.encode(&mut self.bytes);
29        self.num_added += 1;
30        self
31    }
32
33    /// Define a type in this module type.
34    ///
35    /// The returned encoder must be used before adding another definition.
36    #[must_use = "the encoder must be used to encode the type"]
37    pub fn ty(&mut self) -> CoreTypeEncoder<'_> {
38        self.bytes.push(0x01);
39        self.num_added += 1;
40        self.types_added += 1;
41        CoreTypeEncoder {
42            push_prefix_if_component_core_type: false,
43            bytes: &mut self.bytes,
44        }
45    }
46
47    /// Defines an outer core type alias in this module type.
48    pub fn alias_outer_core_type(&mut self, count: u32, index: u32) -> &mut Self {
49        self.bytes.push(0x02);
50        self.bytes.push(CORE_TYPE_SORT);
51        self.bytes.push(0x01); // outer
52        count.encode(&mut self.bytes);
53        index.encode(&mut self.bytes);
54        self.num_added += 1;
55        self.types_added += 1;
56        self
57    }
58
59    /// Defines an export in this module type.
60    pub fn export(&mut self, name: &str, ty: EntityType) -> &mut Self {
61        self.bytes.push(0x03);
62        name.encode(&mut self.bytes);
63        ty.encode(&mut self.bytes);
64        self.num_added += 1;
65        self
66    }
67
68    /// Gets the number of types that have been added to this module type.
69    pub fn type_count(&self) -> u32 {
70        self.types_added
71    }
72}
73
74impl Encode for ModuleType {
75    fn encode(&self, sink: &mut Vec<u8>) {
76        sink.push(0x50);
77        self.num_added.encode(sink);
78        sink.extend(&self.bytes);
79    }
80}
81
82/// Used to encode core types.
83#[derive(Debug)]
84pub struct ComponentCoreTypeEncoder<'a>(pub(crate) &'a mut Vec<u8>);
85
86impl<'a> ComponentCoreTypeEncoder<'a> {
87    /// Define a module type.
88    pub fn module(self, ty: &ModuleType) {
89        ty.encode(self.0);
90    }
91
92    /// Define any core type other than a module type.
93    #[must_use = "the encoder must be used to encode the type"]
94    pub fn core(self) -> CoreTypeEncoder<'a> {
95        CoreTypeEncoder {
96            bytes: self.0,
97            push_prefix_if_component_core_type: true,
98        }
99    }
100}
101
102/// An encoder for the core type section of WebAssembly components.
103///
104/// # Example
105///
106/// ```rust
107/// use wasm_encoder::{Component, CoreTypeSection, ModuleType};
108///
109/// let mut types = CoreTypeSection::new();
110///
111/// types.ty().module(&ModuleType::new());
112///
113/// let mut component = Component::new();
114/// component.section(&types);
115///
116/// let bytes = component.finish();
117/// ```
118#[derive(Clone, Debug, Default)]
119pub struct CoreTypeSection {
120    bytes: Vec<u8>,
121    num_added: u32,
122}
123
124impl CoreTypeSection {
125    /// Create a new core type section encoder.
126    pub fn new() -> Self {
127        Self::default()
128    }
129
130    /// The number of types in the section.
131    pub fn len(&self) -> u32 {
132        self.num_added
133    }
134
135    /// Determines if the section is empty.
136    pub fn is_empty(&self) -> bool {
137        self.num_added == 0
138    }
139
140    /// Encode a type into this section.
141    ///
142    /// The returned encoder must be finished before adding another type.
143    #[must_use = "the encoder must be used to encode the type"]
144    pub fn ty(&mut self) -> ComponentCoreTypeEncoder<'_> {
145        self.num_added += 1;
146        ComponentCoreTypeEncoder(&mut self.bytes)
147    }
148}
149
150impl Encode for CoreTypeSection {
151    fn encode(&self, sink: &mut Vec<u8>) {
152        encode_section(sink, self.num_added, &self.bytes);
153    }
154}
155
156impl ComponentSection for CoreTypeSection {
157    fn id(&self) -> u8 {
158        ComponentSectionId::CoreType.into()
159    }
160}
161
162/// Represents a component type.
163#[derive(Debug, Clone, Default)]
164pub struct ComponentType {
165    bytes: Vec<u8>,
166    num_added: u32,
167    core_types_added: u32,
168    types_added: u32,
169    instances_added: u32,
170}
171
172impl ComponentType {
173    /// Creates a new component type.
174    pub fn new() -> Self {
175        Self::default()
176    }
177
178    /// Define a core type in this component type.
179    ///
180    /// The returned encoder must be used before adding another definition.
181    #[must_use = "the encoder must be used to encode the type"]
182    pub fn core_type(&mut self) -> ComponentCoreTypeEncoder<'_> {
183        self.bytes.push(0x00);
184        self.num_added += 1;
185        self.core_types_added += 1;
186        ComponentCoreTypeEncoder(&mut self.bytes)
187    }
188
189    /// Define a type in this component type.
190    ///
191    /// The returned encoder must be used before adding another definition.
192    #[must_use = "the encoder must be used to encode the type"]
193    pub fn ty(&mut self) -> ComponentTypeEncoder<'_> {
194        self.bytes.push(0x01);
195        self.num_added += 1;
196        self.types_added += 1;
197        ComponentTypeEncoder(&mut self.bytes)
198    }
199
200    /// Defines an alias for an exported item of a prior instance or an
201    /// outer type.
202    pub fn alias(&mut self, alias: Alias<'_>) -> &mut Self {
203        self.bytes.push(0x02);
204        alias.encode(&mut self.bytes);
205        self.num_added += 1;
206        match &alias {
207            Alias::InstanceExport {
208                kind: ComponentExportKind::Type,
209                ..
210            }
211            | Alias::Outer {
212                kind: ComponentOuterAliasKind::Type,
213                ..
214            } => self.types_added += 1,
215            Alias::Outer {
216                kind: ComponentOuterAliasKind::CoreType,
217                ..
218            } => self.core_types_added += 1,
219            Alias::InstanceExport {
220                kind: ComponentExportKind::Instance,
221                ..
222            } => self.instances_added += 1,
223            _ => {}
224        }
225        self
226    }
227
228    /// Defines an import in this component type.
229    pub fn import<'a>(
230        &mut self,
231        name: impl Into<ComponentExternName<'a>>,
232        ty: ComponentTypeRef,
233    ) -> &mut Self {
234        self.bytes.push(0x03);
235        name.into().encode(&mut self.bytes);
236        ty.encode(&mut self.bytes);
237        self.num_added += 1;
238        match ty {
239            ComponentTypeRef::Type(..) => self.types_added += 1,
240            ComponentTypeRef::Instance(..) => self.instances_added += 1,
241            _ => {}
242        }
243        self
244    }
245
246    /// Defines an export in this component type.
247    pub fn export<'a>(
248        &mut self,
249        name: impl Into<ComponentExternName<'a>>,
250        ty: ComponentTypeRef,
251    ) -> &mut Self {
252        self.bytes.push(0x04);
253        name.into().encode(&mut self.bytes);
254        ty.encode(&mut self.bytes);
255        self.num_added += 1;
256        match ty {
257            ComponentTypeRef::Type(..) => self.types_added += 1,
258            ComponentTypeRef::Instance(..) => self.instances_added += 1,
259            _ => {}
260        }
261        self
262    }
263
264    /// Gets the number of core types that have been added to this component type.
265    pub fn core_type_count(&self) -> u32 {
266        self.core_types_added
267    }
268
269    /// Gets the number of types that have been added or aliased in this component type.
270    pub fn type_count(&self) -> u32 {
271        self.types_added
272    }
273
274    /// Gets the number of instances that have been defined in this component
275    /// type through imports, exports, or aliases.
276    pub fn instance_count(&self) -> u32 {
277        self.instances_added
278    }
279}
280
281impl Encode for ComponentType {
282    fn encode(&self, sink: &mut Vec<u8>) {
283        sink.push(0x41);
284        self.num_added.encode(sink);
285        sink.extend(&self.bytes);
286    }
287}
288
289/// Represents an instance type.
290#[derive(Debug, Clone, Default)]
291pub struct InstanceType(ComponentType);
292
293impl InstanceType {
294    /// Creates a new instance type.
295    pub fn new() -> Self {
296        Self::default()
297    }
298
299    /// Define a core type in this instance type.
300    ///
301    /// The returned encoder must be used before adding another definition.
302    #[must_use = "the encoder must be used to encode the type"]
303    pub fn core_type(&mut self) -> ComponentCoreTypeEncoder<'_> {
304        self.0.core_type()
305    }
306
307    /// Define a type in this instance type.
308    ///
309    /// The returned encoder must be used before adding another definition.
310    #[must_use = "the encoder must be used to encode the type"]
311    pub fn ty(&mut self) -> ComponentTypeEncoder<'_> {
312        self.0.ty()
313    }
314
315    /// Defines an outer core type alias in this component type.
316    pub fn alias(&mut self, alias: Alias<'_>) -> &mut Self {
317        self.0.alias(alias);
318        self
319    }
320
321    /// Defines an export in this instance type.
322    pub fn export<'a>(
323        &mut self,
324        name: impl Into<ComponentExternName<'a>>,
325        ty: ComponentTypeRef,
326    ) -> &mut Self {
327        self.0.export(name, ty);
328        self
329    }
330
331    /// Gets the number of core types that have been added to this instance type.
332    pub fn core_type_count(&self) -> u32 {
333        self.0.core_types_added
334    }
335
336    /// Gets the number of types that have been added or aliased in this instance type.
337    pub fn type_count(&self) -> u32 {
338        self.0.types_added
339    }
340
341    /// Gets the number of instances that have been imported or exported or
342    /// aliased in this instance type.
343    pub fn instance_count(&self) -> u32 {
344        self.0.instances_added
345    }
346
347    /// Returns whether or not this instance type is empty.
348    pub fn is_empty(&self) -> bool {
349        self.0.num_added == 0
350    }
351
352    /// Returns the number of entries added to this instance types.
353    pub fn len(&self) -> u32 {
354        self.0.num_added
355    }
356}
357
358impl Encode for InstanceType {
359    fn encode(&self, sink: &mut Vec<u8>) {
360        sink.push(0x42);
361        self.0.num_added.encode(sink);
362        sink.extend(&self.0.bytes);
363    }
364}
365
366/// Used to encode component function types.
367#[derive(Debug)]
368pub struct ComponentFuncTypeEncoder<'a> {
369    async_encoded: bool,
370    params_encoded: bool,
371    results_encoded: bool,
372    sink: &'a mut Vec<u8>,
373}
374
375impl<'a> ComponentFuncTypeEncoder<'a> {
376    fn new(sink: &'a mut Vec<u8>) -> Self {
377        Self {
378            async_encoded: false,
379            params_encoded: false,
380            results_encoded: false,
381            sink,
382        }
383    }
384
385    /// Indicates whether this is an `async` function or not.
386    ///
387    /// If this function is not invoked then the function type will not be
388    /// `async`.
389    ///
390    /// # Panics
391    ///
392    /// This method will panic if parameters or results have already been
393    /// encoded.
394    pub fn async_(&mut self, is_async: bool) -> &mut Self {
395        assert!(!self.params_encoded);
396        assert!(!self.results_encoded);
397        assert!(!self.async_encoded);
398        self.async_encoded = true;
399        if is_async {
400            self.sink.push(0x43);
401        } else {
402            self.sink.push(0x40);
403        }
404        self
405    }
406
407    /// Defines named parameters.
408    ///
409    /// Parameters must be defined before defining results.
410    ///
411    /// # Panics
412    ///
413    /// This method will panic if the function is called twice since parameters
414    /// can only be encoded once.
415    pub fn params<'b, P, T>(&mut self, params: P) -> &mut Self
416    where
417        P: IntoIterator<Item = (&'b str, T)>,
418        P::IntoIter: ExactSizeIterator,
419        T: Into<ComponentValType>,
420    {
421        assert!(!self.params_encoded);
422        if !self.async_encoded {
423            self.async_(false);
424        }
425        self.params_encoded = true;
426        let params = params.into_iter();
427        params.len().encode(self.sink);
428        for (name, ty) in params {
429            name.encode(self.sink);
430            ty.into().encode(self.sink);
431        }
432        self
433    }
434
435    /// Defines a single unnamed result.
436    ///
437    /// This method cannot be used with `results`.
438    ///
439    /// # Panics
440    ///
441    /// This method will panic if the function is called twice, called before
442    /// the `params` method, or called in addition to the `results` method.
443    pub fn result(&mut self, ty: Option<ComponentValType>) -> &mut Self {
444        assert!(self.async_encoded);
445        assert!(self.params_encoded);
446        assert!(!self.results_encoded);
447        self.results_encoded = true;
448        encode_resultlist(self.sink, ty);
449        self
450    }
451}
452
453pub(crate) fn encode_resultlist(sink: &mut Vec<u8>, ty: Option<ComponentValType>) {
454    match ty {
455        Some(ty) => {
456            sink.push(0x00);
457            ty.encode(sink);
458        }
459        None => {
460            sink.push(0x01);
461            sink.push(0x00);
462        }
463    }
464}
465
466/// Used to encode component and instance types.
467#[derive(Debug)]
468pub struct ComponentTypeEncoder<'a>(&'a mut Vec<u8>);
469
470impl<'a> ComponentTypeEncoder<'a> {
471    /// Define a component type.
472    pub fn component(self, ty: &ComponentType) {
473        ty.encode(self.0);
474    }
475
476    /// Define an instance type.
477    pub fn instance(self, ty: &InstanceType) {
478        ty.encode(self.0);
479    }
480
481    /// Define a function type.
482    pub fn function(self) -> ComponentFuncTypeEncoder<'a> {
483        ComponentFuncTypeEncoder::new(self.0)
484    }
485
486    /// Define a defined component type.
487    ///
488    /// The returned encoder must be used before adding another type.
489    #[must_use = "the encoder must be used to encode the type"]
490    pub fn defined_type(self) -> ComponentDefinedTypeEncoder<'a> {
491        ComponentDefinedTypeEncoder(self.0)
492    }
493
494    /// Define a resource type.
495    pub fn resource(self, rep: ValType, dtor: Option<u32>) {
496        self.0.push(0x3f);
497        rep.encode(self.0);
498        match dtor {
499            Some(i) => {
500                self.0.push(0x01);
501                i.encode(self.0);
502            }
503            None => self.0.push(0x00),
504        }
505    }
506}
507
508/// Represents a primitive component value type.
509#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
510pub enum PrimitiveValType {
511    /// The type is a boolean.
512    Bool,
513    /// The type is a signed 8-bit integer.
514    S8,
515    /// The type is an unsigned 8-bit integer.
516    U8,
517    /// The type is a signed 16-bit integer.
518    S16,
519    /// The type is an unsigned 16-bit integer.
520    U16,
521    /// The type is a signed 32-bit integer.
522    S32,
523    /// The type is an unsigned 32-bit integer.
524    U32,
525    /// The type is a signed 64-bit integer.
526    S64,
527    /// The type is an unsigned 64-bit integer.
528    U64,
529    /// The type is a 32-bit floating point number with only one NaN.
530    F32,
531    /// The type is a 64-bit floating point number with only one NaN.
532    F64,
533    /// The type is a Unicode character.
534    Char,
535    /// The type is a string.
536    String,
537    /// Type for `error-context` added with async support in the component model.
538    ErrorContext,
539}
540
541impl Encode for PrimitiveValType {
542    fn encode(&self, sink: &mut Vec<u8>) {
543        sink.push(match self {
544            Self::Bool => 0x7f,
545            Self::S8 => 0x7e,
546            Self::U8 => 0x7d,
547            Self::S16 => 0x7c,
548            Self::U16 => 0x7b,
549            Self::S32 => 0x7a,
550            Self::U32 => 0x79,
551            Self::S64 => 0x78,
552            Self::U64 => 0x77,
553            Self::F32 => 0x76,
554            Self::F64 => 0x75,
555            Self::Char => 0x74,
556            Self::String => 0x73,
557            Self::ErrorContext => 0x64,
558        });
559    }
560}
561
562/// Represents a component value type.
563#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
564pub enum ComponentValType {
565    /// The value is a primitive type.
566    Primitive(PrimitiveValType),
567    /// The value is to a defined value type.
568    ///
569    /// The type index must be to a value type.
570    Type(u32),
571}
572
573impl Encode for ComponentValType {
574    fn encode(&self, sink: &mut Vec<u8>) {
575        match self {
576            Self::Primitive(ty) => ty.encode(sink),
577            Self::Type(index) => (*index as i64).encode(sink),
578        }
579    }
580}
581
582impl From<PrimitiveValType> for ComponentValType {
583    fn from(ty: PrimitiveValType) -> Self {
584        Self::Primitive(ty)
585    }
586}
587
588/// Used for encoding component defined types.
589#[derive(Debug)]
590pub struct ComponentDefinedTypeEncoder<'a>(&'a mut Vec<u8>);
591
592impl ComponentDefinedTypeEncoder<'_> {
593    /// Define a primitive value type.
594    pub fn primitive(self, ty: PrimitiveValType) {
595        ty.encode(self.0);
596    }
597
598    /// Define a record type.
599    pub fn record<'a, F, T>(self, fields: F)
600    where
601        F: IntoIterator<Item = (&'a str, T)>,
602        F::IntoIter: ExactSizeIterator,
603        T: Into<ComponentValType>,
604    {
605        let fields = fields.into_iter();
606        self.0.push(0x72);
607        fields.len().encode(self.0);
608        for (name, ty) in fields {
609            name.encode(self.0);
610            ty.into().encode(self.0);
611        }
612    }
613
614    /// Define a variant type.
615    pub fn variant<'a, C>(self, cases: C)
616    where
617        C: IntoIterator<Item = (&'a str, Option<ComponentValType>)>,
618        C::IntoIter: ExactSizeIterator,
619    {
620        let cases = cases.into_iter();
621        self.0.push(0x71);
622        cases.len().encode(self.0);
623        for (name, ty) in cases {
624            name.encode(self.0);
625            ty.encode(self.0);
626            self.0.push(0x00);
627        }
628    }
629
630    /// Define a list type.
631    pub fn list(self, ty: impl Into<ComponentValType>) {
632        self.0.push(0x70);
633        ty.into().encode(self.0);
634    }
635
636    /// Define a map type.
637    pub fn map(self, key: impl Into<ComponentValType>, value: impl Into<ComponentValType>) {
638        self.0.push(0x63);
639        key.into().encode(self.0);
640        value.into().encode(self.0);
641    }
642
643    /// Define a fixed-length list type.
644    pub fn fixed_length_list(self, ty: impl Into<ComponentValType>, elements: u32) {
645        self.0.push(0x67);
646        ty.into().encode(self.0);
647        elements.encode(self.0);
648    }
649
650    /// Define a tuple type.
651    pub fn tuple<I, T>(self, types: I)
652    where
653        I: IntoIterator<Item = T>,
654        I::IntoIter: ExactSizeIterator,
655        T: Into<ComponentValType>,
656    {
657        let types = types.into_iter();
658        self.0.push(0x6F);
659        types.len().encode(self.0);
660        for ty in types {
661            ty.into().encode(self.0);
662        }
663    }
664
665    /// Define a flags type.
666    pub fn flags<'a, I>(self, names: I)
667    where
668        I: IntoIterator<Item = &'a str>,
669        I::IntoIter: ExactSizeIterator,
670    {
671        let names = names.into_iter();
672        self.0.push(0x6E);
673        names.len().encode(self.0);
674        for name in names {
675            name.encode(self.0);
676        }
677    }
678
679    /// Define an enum type.
680    pub fn enum_type<'a, I>(self, tags: I)
681    where
682        I: IntoIterator<Item = &'a str>,
683        I::IntoIter: ExactSizeIterator,
684    {
685        let tags = tags.into_iter();
686        self.0.push(0x6D);
687        tags.len().encode(self.0);
688        for tag in tags {
689            tag.encode(self.0);
690        }
691    }
692
693    /// Define an option type.
694    pub fn option(self, ty: impl Into<ComponentValType>) {
695        self.0.push(0x6B);
696        ty.into().encode(self.0);
697    }
698
699    /// Define a result type.
700    pub fn result(self, ok: Option<ComponentValType>, err: Option<ComponentValType>) {
701        self.0.push(0x6A);
702        ok.encode(self.0);
703        err.encode(self.0);
704    }
705
706    /// Define a `own` handle type
707    pub fn own(self, idx: u32) {
708        self.0.push(0x69);
709        idx.encode(self.0);
710    }
711
712    /// Define a `borrow` handle type
713    pub fn borrow(self, idx: u32) {
714        self.0.push(0x68);
715        idx.encode(self.0);
716    }
717
718    /// Define a `future` type with the specified payload.
719    pub fn future(self, payload: Option<ComponentValType>) {
720        self.0.push(0x65);
721        payload.encode(self.0);
722    }
723
724    /// Define a `stream` type with the specified payload.
725    pub fn stream(self, payload: Option<ComponentValType>) {
726        self.0.push(0x66);
727        payload.encode(self.0);
728    }
729}
730
731/// An encoder for the type section of WebAssembly components.
732///
733/// # Example
734///
735/// ```rust
736/// use wasm_encoder::{Component, ComponentTypeSection, PrimitiveValType};
737///
738/// let mut types = ComponentTypeSection::new();
739///
740/// // Define a function type of `[string, string] -> string`.
741/// types
742///   .function()
743///   .params(
744///     [
745///       ("a", PrimitiveValType::String),
746///       ("b", PrimitiveValType::String)
747///     ]
748///   )
749///   .result(Some(PrimitiveValType::String.into()));
750///
751/// let mut component = Component::new();
752/// component.section(&types);
753///
754/// let bytes = component.finish();
755/// ```
756#[derive(Clone, Debug, Default)]
757pub struct ComponentTypeSection {
758    bytes: Vec<u8>,
759    num_added: u32,
760}
761
762impl ComponentTypeSection {
763    /// Create a new component type section encoder.
764    pub fn new() -> Self {
765        Self::default()
766    }
767
768    /// The number of types in the section.
769    pub fn len(&self) -> u32 {
770        self.num_added
771    }
772
773    /// Determines if the section is empty.
774    pub fn is_empty(&self) -> bool {
775        self.num_added == 0
776    }
777
778    /// Encode a type into this section.
779    ///
780    /// The returned encoder must be finished before adding another type.
781    #[must_use = "the encoder must be used to encode the type"]
782    pub fn ty(&mut self) -> ComponentTypeEncoder<'_> {
783        self.num_added += 1;
784        ComponentTypeEncoder(&mut self.bytes)
785    }
786
787    /// Define a component type in this type section.
788    pub fn component(&mut self, ty: &ComponentType) -> &mut Self {
789        self.ty().component(ty);
790        self
791    }
792
793    /// Define an instance type in this type section.
794    pub fn instance(&mut self, ty: &InstanceType) -> &mut Self {
795        self.ty().instance(ty);
796        self
797    }
798
799    /// Define a function type in this type section.
800    pub fn function(&mut self) -> ComponentFuncTypeEncoder<'_> {
801        self.ty().function()
802    }
803
804    /// Add a component defined type to this type section.
805    ///
806    /// The returned encoder must be used before adding another type.
807    #[must_use = "the encoder must be used to encode the type"]
808    pub fn defined_type(&mut self) -> ComponentDefinedTypeEncoder<'_> {
809        self.ty().defined_type()
810    }
811
812    /// Defines a new resource type.
813    pub fn resource(&mut self, rep: ValType, dtor: Option<u32>) -> &mut Self {
814        self.ty().resource(rep, dtor);
815        self
816    }
817}
818
819impl Encode for ComponentTypeSection {
820    fn encode(&self, sink: &mut Vec<u8>) {
821        encode_section(sink, self.num_added, &self.bytes);
822    }
823}
824
825impl ComponentSection for ComponentTypeSection {
826    fn id(&self) -> u8 {
827        ComponentSectionId::Type.into()
828    }
829}