use std::borrow::Cow; use super::*; use crate::{encoding_size, CustomSection, Encode, ExportKind, NameMap, SectionId}; /// Encoding for the `component-name` custom section which assigns /// human-readable names to items within a component. #[derive(Clone, Debug, Default)] pub struct ComponentNameSection { bytes: Vec, } enum Subsection { Component, Decls, } impl ComponentNameSection { /// Creates a new blank `name` custom section. pub fn new() -> Self { Self::default() } /// Appends a component name subsection to this section. /// /// This will indicate that the name of the entire component should be the /// `name` specified. Note that this should be encoded first before other /// subsections. pub fn component(&mut self, name: &str) { let len = encoding_size(u32::try_from(name.len()).unwrap()); self.subsection_header(Subsection::Component, len + name.len()); name.encode(&mut self.bytes); } /// Appends a decls name subsection to name core functions within the /// component. pub fn core_funcs(&mut self, names: &NameMap) { self.core_decls(ExportKind::Func as u8, names) } /// Appends a decls name subsection to name core tables within the /// component. pub fn core_tables(&mut self, names: &NameMap) { self.core_decls(ExportKind::Table as u8, names) } /// Appends a decls name subsection to name core memories within the /// component. pub fn core_memories(&mut self, names: &NameMap) { self.core_decls(ExportKind::Memory as u8, names) } /// Appends a decls name subsection to name core globals within the /// component. pub fn core_globals(&mut self, names: &NameMap) { self.core_decls(ExportKind::Global as u8, names) } /// Appends a decls name subsection to name core types within the /// component. pub fn core_types(&mut self, names: &NameMap) { self.core_decls(CORE_TYPE_SORT, names) } /// Appends a decls name subsection to name core modules within the /// component. pub fn core_modules(&mut self, names: &NameMap) { self.core_decls(CORE_MODULE_SORT, names) } /// Appends a decls name subsection to name core instances within the /// component. pub fn core_instances(&mut self, names: &NameMap) { self.core_decls(CORE_INSTANCE_SORT, names) } /// Appends a decls name subsection to name component functions within the /// component. pub fn funcs(&mut self, names: &NameMap) { self.component_decls(FUNCTION_SORT, names) } /// Appends a decls name subsection to name component values within the /// component. pub fn values(&mut self, names: &NameMap) { self.component_decls(VALUE_SORT, names) } /// Appends a decls name subsection to name component type within the /// component. pub fn types(&mut self, names: &NameMap) { self.component_decls(TYPE_SORT, names) } /// Appends a decls name subsection to name components within the /// component. pub fn components(&mut self, names: &NameMap) { self.component_decls(COMPONENT_SORT, names) } /// Appends a decls name subsection to name component instances within the /// component. pub fn instances(&mut self, names: &NameMap) { self.component_decls(INSTANCE_SORT, names) } fn component_decls(&mut self, kind: u8, names: &NameMap) { self.subsection_header(Subsection::Decls, 1 + names.size()); self.bytes.push(kind); names.encode(&mut self.bytes); } fn core_decls(&mut self, kind: u8, names: &NameMap) { self.subsection_header(Subsection::Decls, 2 + names.size()); self.bytes.push(CORE_SORT); self.bytes.push(kind); names.encode(&mut self.bytes); } fn subsection_header(&mut self, id: Subsection, len: usize) { self.bytes.push(id as u8); len.encode(&mut self.bytes); } /// Returns whether this section is empty, or nothing has been encoded. pub fn is_empty(&self) -> bool { self.bytes.is_empty() } /// View the encoded section as a CustomSection. pub fn as_custom<'a>(&'a self) -> CustomSection<'a> { CustomSection { name: "component-name".into(), data: Cow::Borrowed(&self.bytes), } } } impl Encode for ComponentNameSection { fn encode(&self, sink: &mut Vec) { self.as_custom().encode(sink); } } impl ComponentSection for ComponentNameSection { fn id(&self) -> u8 { SectionId::Custom.into() } }