molecule_codegen/ast/verified/
default_content.rs

1use molecule::{pack_number, Number, NUMBER_SIZE};
2
3pub trait DefaultContent {
4    fn default_content(&self) -> Vec<u8>;
5}
6
7impl DefaultContent for super::Primitive {
8    fn default_content(&self) -> Vec<u8> {
9        vec![0]
10    }
11}
12
13impl DefaultContent for super::Option_ {
14    fn default_content(&self) -> Vec<u8> {
15        Vec::new()
16    }
17}
18
19impl DefaultContent for super::Union {
20    fn default_content(&self) -> Vec<u8> {
21        let first_union_item = self.items().first().unwrap();
22        let inner_content = first_union_item.typ.default_content();
23        let total_size = NUMBER_SIZE + inner_content.len();
24        let mut content = Vec::with_capacity(total_size);
25        content.extend_from_slice(&pack_number(first_union_item.id() as Number));
26        content.extend_from_slice(&inner_content);
27        content
28    }
29}
30
31impl DefaultContent for super::Array {
32    fn default_content(&self) -> Vec<u8> {
33        vec![0; self.total_size()]
34    }
35}
36
37impl DefaultContent for super::Struct {
38    fn default_content(&self) -> Vec<u8> {
39        vec![0; self.total_size()]
40    }
41}
42
43impl DefaultContent for super::FixVec {
44    fn default_content(&self) -> Vec<u8> {
45        let item_count = 0;
46        let mut content = Vec::with_capacity(NUMBER_SIZE);
47        content.extend_from_slice(&pack_number(item_count as Number));
48        content
49    }
50}
51
52impl DefaultContent for super::DynVec {
53    fn default_content(&self) -> Vec<u8> {
54        let total_size = NUMBER_SIZE;
55        let mut content = Vec::with_capacity(NUMBER_SIZE);
56        content.extend_from_slice(&pack_number(total_size as Number));
57        content
58    }
59}
60
61impl DefaultContent for super::Table {
62    fn default_content(&self) -> Vec<u8> {
63        let field_count = self.fields().len();
64        let (total_size, content) = if field_count == 0 {
65            let total_size = NUMBER_SIZE;
66            let mut content = Vec::with_capacity(total_size);
67            content.extend_from_slice(&pack_number(total_size as Number));
68            (total_size, content)
69        } else {
70            let (total_size, offsets, field_data) = self.fields().iter().fold(
71                (
72                    NUMBER_SIZE * (field_count + 1),
73                    Vec::with_capacity(field_count),
74                    Vec::with_capacity(field_count),
75                ),
76                |(mut current_offset, mut offsets, mut field_data), field| {
77                    offsets.push(current_offset);
78                    let data = field.typ.default_content();
79                    current_offset += data.len();
80                    field_data.push(data);
81                    (current_offset, offsets, field_data)
82                },
83            );
84            let mut content = Vec::with_capacity(total_size);
85            content.extend_from_slice(&pack_number(total_size as Number));
86            for offset in offsets.into_iter() {
87                content.extend_from_slice(&pack_number(offset as Number));
88            }
89            for data in field_data.into_iter() {
90                content.extend_from_slice(&data);
91            }
92            (total_size, content)
93        };
94        assert_eq!(content.len(), total_size);
95        content
96    }
97}
98
99impl DefaultContent for super::TopDecl {
100    fn default_content(&self) -> Vec<u8> {
101        match self {
102            super::TopDecl::Primitive(inner) => inner.default_content(),
103            super::TopDecl::Option_(inner) => inner.default_content(),
104            super::TopDecl::Union(inner) => inner.default_content(),
105            super::TopDecl::Array(inner) => inner.default_content(),
106            super::TopDecl::Struct(inner) => inner.default_content(),
107            super::TopDecl::FixVec(inner) => inner.default_content(),
108            super::TopDecl::DynVec(inner) => inner.default_content(),
109            super::TopDecl::Table(inner) => inner.default_content(),
110        }
111    }
112}