1#[derive(Default)]
13pub struct Structure {
14 fields: Vec<Field>,
15}
16
17impl Structure {
18 fn alignment(&self) -> usize {
19 let mut alignment = 1;
20 for field in &self.fields {
21 if field.alignment() > alignment {
22 alignment = field.alignment();
23 }
24 }
25 alignment
26 }
27
28 pub fn field(mut self, field: Field) -> Self {
30 self.fields.push(field);
31 self
32 }
33
34 pub fn encode_persistent(&self) -> Vec<u8> {
38 let mut buf = Vec::new();
39
40 buf.push(0); buf.push(1); buf.extend(2u16.to_le_bytes()); buf.extend([0; 4]); self.encode(&mut buf);
48
49 buf
50 }
51
52 pub fn encode(&self, buf: &mut Vec<u8>) {
54 self.encode_inline(buf);
55 buf.pad_to(8);
58 }
59
60 pub fn encode_inline(&self, buf: &mut Vec<u8>) {
61 self.encode_fields(buf);
62 }
63
64 pub fn encode_fields(&self, buf: &mut Vec<u8>) {
65 if self.fields.is_empty() {
67 BasicField::UInt8(0).encode_inline(buf);
73 } else {
74 for field in &self.fields {
76 field.encode_inline(buf);
77 }
78
79 for field in &self.fields {
80 field.encode_out_of_line(buf);
81 }
82 buf.pad_to(self.alignment());
83 }
84 }
85}
86
87#[derive(Default)]
89pub struct Box {
90 inner: Option<Structure>,
91}
92
93impl Box {
94 pub fn set_present(self) -> Self {
95 Box {
96 inner: match self.inner {
97 Some(s) => Some(s),
98 None => Some(Structure::default()),
99 },
100 }
101 }
102 pub fn field(mut self, field: Field) -> Self {
104 self.inner = match self.inner {
105 Some(s) => Some(s.field(field)),
106 None => Some(Structure::default().field(field)),
107 };
108 self
109 }
110
111 fn alignment(&self) -> usize {
112 8
113 }
114
115 fn encode_inline(&self, buf: &mut Vec<u8>) {
116 match &self.inner {
120 None => buf.extend(0u64.to_le_bytes()),
121 Some(_) => buf.extend(u64::MAX.to_le_bytes()),
122 }
123 }
124
125 fn encode_out_of_line(&self, buf: &mut Vec<u8>) {
126 match &self.inner {
127 None => (),
128 Some(s) => s.encode_fields(buf),
129 }
130 }
131}
132
133pub enum Field {
135 Basic(BasicField),
136 Vector(VectorField),
137 Struct(Structure),
138 Box(Box),
139}
140
141impl Field {
142 fn alignment(&self) -> usize {
143 match self {
144 Self::Basic(b) => b.alignment(),
145 Self::Vector(l) => l.alignment(),
146 Self::Struct(s) => s.alignment(),
147 Self::Box(s) => s.alignment(),
148 }
149 }
150
151 fn encode_inline(&self, buf: &mut Vec<u8>) {
152 buf.pad_to(self.alignment());
153 match self {
154 Self::Basic(b) => b.encode_inline(buf),
155 Self::Vector(l) => l.encode_inline(buf),
156 Self::Struct(s) => s.encode_inline(buf),
157 Self::Box(s) => s.encode_inline(buf),
158 }
159 }
160
161 fn encode_out_of_line(&self, buf: &mut Vec<u8>) {
162 match self {
163 Self::Basic(_) => (),
164 Self::Vector(l) => {
165 buf.pad_to(8);
167 l.encode_out_of_line(buf);
168 }
169 Self::Struct(_) => (),
170 Self::Box(s) => {
171 buf.pad_to(8);
173 s.encode_out_of_line(buf)
174 }
175 }
176 }
177}
178
179pub enum BasicField {
180 Bool(bool),
181 UInt8(u8),
182 UInt16(u16),
183 UInt32(u32),
184 UInt64(u64),
185 Int8(i8),
186 Int16(i16),
187 Int32(i32),
188 Int64(i64),
189}
190
191impl BasicField {
192 fn encode_inline(&self, buf: &mut Vec<u8>) {
193 match self {
194 Self::Bool(b) => buf.push(if *b { 1u8 } else { 0u8 }),
195 Self::UInt8(n) => buf.push(*n),
196 Self::UInt16(n) => buf.extend(n.to_le_bytes()),
197 Self::UInt32(n) => buf.extend(n.to_le_bytes()),
198 Self::UInt64(n) => buf.extend(n.to_le_bytes()),
199 Self::Int8(n) => buf.extend(n.to_le_bytes()),
200 Self::Int16(n) => buf.extend(n.to_le_bytes()),
201 Self::Int32(n) => buf.extend(n.to_le_bytes()),
202 Self::Int64(n) => buf.extend(n.to_le_bytes()),
203 }
204 }
205
206 fn alignment(&self) -> usize {
207 match self {
208 Self::Bool(_) | Self::UInt8(_) | Self::Int8(_) => 1,
209 Self::UInt16(_) | Self::Int16(_) => 2,
210 Self::UInt32(_) | Self::Int32(_) => 4,
211 _ => 8,
212 }
213 }
214}
215
216pub enum VectorField {
217 Null,
219 BoolVector(Vec<bool>),
220 UInt8Vector(Vec<u8>),
221 UInt16Vector(Vec<u16>),
222 UInt32Vector(Vec<u32>),
223 UInt64Vector(Vec<u64>),
224 Int8Vector(Vec<i8>),
225 Int16Vector(Vec<i16>),
226 Int32Vector(Vec<i32>),
227 Int64Vector(Vec<i64>),
228 UInt8VectorVector(Vec<Vec<u8>>),
230}
231
232impl VectorField {
233 fn alignment(&self) -> usize {
234 8
235 }
236
237 fn encode_inline(&self, buf: &mut Vec<u8>) {
238 let size = match self {
242 Self::Null => 0,
243 Self::BoolVector(v) => v.len(),
244 Self::UInt8Vector(v) => v.len(),
245 Self::UInt16Vector(v) => v.len(),
246 Self::UInt32Vector(v) => v.len(),
247 Self::UInt64Vector(v) => v.len(),
248 Self::Int8Vector(v) => v.len(),
249 Self::Int16Vector(v) => v.len(),
250 Self::Int32Vector(v) => v.len(),
251 Self::Int64Vector(v) => v.len(),
252 Self::UInt8VectorVector(v) => v.len(),
253 } as u64;
254 buf.extend(size.to_le_bytes());
255
256 match self {
260 Self::Null => buf.extend(0u64.to_le_bytes()),
261 _ => buf.extend(u64::MAX.to_le_bytes()),
262 }
263 }
264
265 fn encode_out_of_line(&self, buf: &mut Vec<u8>) {
266 match self {
267 Self::Null => (),
268 Self::BoolVector(v) => {
269 for b in v {
270 BasicField::Bool(*b).encode_inline(buf);
271 }
272 }
273 Self::UInt8Vector(v) => buf.extend(v),
274 Self::UInt16Vector(v) => {
275 for n in v {
276 BasicField::UInt16(*n).encode_inline(buf);
277 }
278 }
279 Self::UInt32Vector(v) => {
280 for n in v {
281 BasicField::UInt32(*n).encode_inline(buf);
282 }
283 }
284 Self::UInt64Vector(v) => {
285 for n in v {
286 BasicField::UInt64(*n).encode_inline(buf);
287 }
288 }
289 Self::Int8Vector(v) => {
290 for n in v {
291 BasicField::Int8(*n).encode_inline(buf);
292 }
293 }
294 Self::Int16Vector(v) => {
295 for n in v {
296 BasicField::Int16(*n).encode_inline(buf);
297 }
298 }
299 Self::Int32Vector(v) => {
300 for n in v {
301 BasicField::Int32(*n).encode_inline(buf);
302 }
303 }
304 Self::Int64Vector(v) => {
305 for n in v {
306 BasicField::Int64(*n).encode_inline(buf);
307 }
308 }
309 Self::UInt8VectorVector(outer) => {
310 let as_fields = outer
311 .iter()
312 .map(|v| Field::Vector(VectorField::UInt8Vector(v.clone())))
313 .collect::<Vec<_>>();
314
315 for field in &as_fields {
316 field.encode_inline(buf);
317 }
318 for field in &as_fields {
319 field.encode_out_of_line(buf);
320 }
321 }
322 }
323 }
324}
325
326trait Padding {
327 fn pad_to(&mut self, align: usize);
328}
329
330impl Padding for Vec<u8> {
331 fn pad_to(&mut self, align: usize) {
332 let start_len = self.len();
333 let num_bytes = (align - (start_len % align)) % align;
334 self.resize(start_len + num_bytes, 0);
335 }
336}