1use crate::header::ZonHeader;
2
3pub struct ZonWriter {
4 pub(crate) buffer: Vec<u8>,
5}
6
7impl ZonWriter {
8 pub fn new() -> Self {
9 let mut writer = Self {
11 buffer: Vec::with_capacity(4096),
12 };
13
14 let header = ZonHeader::default();
16
17 let header_slice = unsafe {
19 std::slice::from_raw_parts(
20 &header as *const ZonHeader as *const u8,
21 std::mem::size_of::<ZonHeader>(),
22 )
23 };
24
25 writer.buffer.extend_from_slice(header_slice);
26 writer
27 }
28
29 pub fn len(&self) -> usize {
30 self.buffer.len()
31 }
32
33 pub fn is_empty(&self) -> bool {
34 self.buffer.is_empty()
35 }
36
37 pub fn as_bytes(&self) -> &[u8] {
38 &self.buffer
39 }
40
41 pub fn write_u32(&mut self, val: u32) -> u32 {
44 let offset = self.buffer.len() as u32;
45 self.buffer.extend_from_slice(&val.to_le_bytes());
46 offset
47 }
48
49 pub fn write_string(&mut self, val: &str) -> u32 {
54 let start_offset = self.buffer.len() as u32;
55 let len = val.len() as u32;
56
57 self.buffer.extend_from_slice(&len.to_le_bytes());
59
60 self.buffer.extend_from_slice(val.as_bytes());
62
63 let current_len = self.buffer.len();
65 let padding_needed = (4 - (current_len % 4)) % 4;
66 for _ in 0..padding_needed {
67 self.buffer.push(0);
68 }
69
70 start_offset
71 }
72
73 pub fn set_root(&mut self, offset: u32) {
76 if self.buffer.len() >= 12 {
78 let bytes = offset.to_le_bytes();
79 self.buffer[8] = bytes[0];
80 self.buffer[9] = bytes[1];
81 self.buffer[10] = bytes[2];
82 self.buffer[11] = bytes[3];
83 }
84 }
85}
86
87impl Default for ZonWriter {
88 fn default() -> Self {
89 Self::new()
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn test_writer_initialization() {
99 let writer = ZonWriter::new();
100 assert_eq!(writer.len(), 64);
101
102 let bytes = writer.as_bytes();
103 assert_eq!(bytes[0], 0x21);
105 assert_eq!(bytes[1], 0x4E);
106 assert_eq!(bytes[2], 0x4F);
107 assert_eq!(bytes[3], 0x5A);
108 }
109
110 #[test]
111 fn test_write_primitive_and_string() {
112 let mut writer = ZonWriter::new();
113
114 let u32_val = 0x12345678;
116 let u32_offset = writer.write_u32(u32_val);
117
118 assert_eq!(u32_offset, 64);
120
121 let string_val = "hello";
126 let str_offset = writer.write_string(string_val);
127
128 assert_eq!(str_offset, 64 + 4); {
132 let bytes = writer.as_bytes();
133
134 let u32_slice = &bytes[64..68];
136 assert_eq!(u32::from_le_bytes(u32_slice.try_into().unwrap()), u32_val);
137
138 let len_slice = &bytes[68..72];
140 assert_eq!(u32::from_le_bytes(len_slice.try_into().unwrap()), 5);
141
142 let str_slice = &bytes[72..77];
144 assert_eq!(str_slice, b"hello");
145
146 assert_eq!(bytes[77], 0);
148 assert_eq!(bytes[78], 0);
149 assert_eq!(bytes[79], 0);
150
151 assert_eq!(bytes.len() % 4, 0);
153 }
154
155 writer.set_root(str_offset);
157
158 {
159 let bytes = writer.as_bytes();
160 let root_slice = &bytes[8..12];
162 assert_eq!(u32::from_le_bytes(root_slice.try_into().unwrap()), str_offset);
163 }
164 }
165}