1use std::borrow::Cow;
2
3use crate::{encoding_size, Encode, Section, SectionId};
4
5/// A custom section holding arbitrary data.
6#[derive(Clone, Debug)]
7pub struct CustomSection<'a> {
8 /// The name of this custom section.
9 pub name: Cow<'a, str>,
10 /// This custom section's data.
11 pub data: Cow<'a, [u8]>,
12}
13
14impl Encode for CustomSection<'_> {
15 fn encode(&self, sink: &mut Vec<u8>) {
16 let encoded_name_len: usize = encoding_size(u32::try_from(self.name.len()).unwrap());
17 (encoded_name_len + self.name.len() + self.data.len()).encode(sink);
18 self.name.encode(sink);
19 sink.extend(&*self.data);
20 }
21}
22
23impl Section for CustomSection<'_> {
24 fn id(&self) -> u8 {
25 SectionId::Custom.into()
26 }
27}
28
29/// A raw custom section where the bytes specified contain the leb-encoded
30/// length of the custom section, the custom section's name, and the custom
31/// section's data.
32#[derive(Clone, Debug)]
33pub struct RawCustomSection<'a>(pub &'a [u8]);
34
35impl Encode for RawCustomSection<'_> {
36 fn encode(&self, sink: &mut Vec<u8>) {
37 sink.extend(self.0);
38 }
39}
40
41impl Section for RawCustomSection<'_> {
42 fn id(&self) -> u8 {
43 SectionId::Custom.into()
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50
51 #[test]
52 fn test_custom_section() {
53 let custom = CustomSection {
54 name: "test".into(),
55 data: Cow::Borrowed(&[11, 22, 33, 44]),
56 };
57
58 let mut encoded = vec![];
59 custom.encode(&mut encoded);
60
61 #[rustfmt::skip]
62 assert_eq!(encoded, vec![
63 // LEB128 length of section.
64 9,
65 // LEB128 length of name.
66 4,
67 // Name.
68 b't', b'e', b's', b't',
69 // Data.
70 11, 22, 33, 44,
71 ]);
72 }
73}
74