1use alloc::{string::String, vec::Vec};
11use core::mem;
12
13use parity_wasm::elements::{self, Serialize};
14
15use crate::{section::SectionKind, Error, Result, Section};
16
17#[derive(Debug)]
19pub struct Module(elements::Module);
20
21impl Module {
22 pub fn new(buf: &[u8]) -> Result<Self> {
24 Ok(Module(elements::Module::from_bytes(buf).map_err(Error)?))
25 }
26
27 pub fn sections(&self) -> Result<impl Iterator<Item = Section<'_>>> {
32 const ERROR_MESSAGE: Error = Error::with_msg("Incorrect Section Order");
33
34 let mut kind = SectionKind::Name;
35 let iter = self.0.custom_sections();
36
37 for section in self.0.custom_sections() {
38 match section.name() {
39 "name" if kind <= SectionKind::Name => {
40 kind = SectionKind::Producers
41 }
42 "producers" if kind <= SectionKind::Producers => {
43 kind = SectionKind::Daku
44 }
45 "daku" if kind <= SectionKind::Daku => {
46 kind = SectionKind::Unknown
47 }
48 "name" | "producers" | "daku" => return Err(ERROR_MESSAGE),
49 _ => {}
50 }
51 }
52
53 Ok(iter.map(|section| Section::Any {
54 name: section.name().into(),
55 data: section.payload().into(),
56 }))
57 }
58
59 pub fn set_section(&mut self, mut section: Section<'_>) -> Option<()> {
62 let (name, data) = section.to_any()?;
63
64 self.0.set_custom_section(name, data.to_vec());
65
66 Some(())
67 }
68
69 pub fn clear_section(
72 &mut self,
73 name: impl AsRef<str>,
74 ) -> Option<Section<'static>> {
75 let mut section = self.0.clear_custom_section(&name)?;
76 let (mut name, mut data) = (String::new(), Vec::new());
77
78 mem::swap(&mut name, section.name_mut());
79 mem::swap(&mut data, section.payload_mut());
80
81 Some(Section::Any {
82 name: name.into(),
83 data: data.into(),
84 })
85 }
86
87 pub fn into_buffer(self) -> Result<Vec<u8>> {
89 let mut v = Vec::new();
90 self.0.serialize(&mut v).map_err(Error)?;
91 Ok(v)
92 }
93}