1use crate::*;
2
3#[derive(Debug, Copy, Clone)]
5pub struct ListLayout {
6 pub(crate) size: usize,
8 len_offset: usize,
10 len_layout: PrimitiveLayout,
12 data_offset: usize,
14 data_layout: ArrayLayout,
16}
17
18impl ListLayout {
19 pub const fn new(
21 size: usize,
22 len_offset: usize,
23 len_layout: PrimitiveLayout,
24 data_offset: usize,
25 data_layout: ArrayLayout,
26 ) -> Self {
27 Self {
28 size,
29 len_offset,
30 len_layout,
31 data_offset,
32 data_layout,
33 }
34 }
35}
36
37pub(crate) const unsafe fn serialize_const_list(
39 ptr: *const (),
40 mut to: ConstVec<u8>,
41 layout: &ListLayout,
42) -> ConstVec<u8> {
43 let len_ptr = ptr.wrapping_byte_offset(layout.len_offset as _);
45 let len = layout.len_layout.read(len_ptr as *const u8) as usize;
46
47 let data_ptr = ptr.wrapping_byte_offset(layout.data_offset as _);
48 let item_layout = layout.data_layout.item_layout;
49 if item_layout.size() == 1 {
51 let slice = std::slice::from_raw_parts(data_ptr as *const u8, len);
52 to = write_bytes(to, slice);
53 }
54 else {
56 let mut i = 0;
57 to = write_array(to, len);
58 while i < len {
59 let item = data_ptr.wrapping_byte_offset((i * item_layout.size()) as _);
60 to = serialize_const_ptr(item, to, item_layout);
61 i += 1;
62 }
63 }
64 to
65}
66
67pub(crate) const fn deserialize_const_list<'a>(
69 from: &'a [u8],
70 layout: &ListLayout,
71 out: &mut [MaybeUninit<u8>],
72) -> Option<&'a [u8]> {
73 let Some((_, len_out)) = out.split_at_mut_checked(layout.len_offset) else {
74 return None;
75 };
76
77 let item_layout = layout.data_layout.item_layout;
79 if item_layout.size() == 1 {
80 let Ok((bytes, new_from)) = take_bytes(from) else {
81 return None;
82 };
83 layout.len_layout.write(bytes.len() as u32, len_out);
85 let Some((_, data_out)) = out.split_at_mut_checked(layout.data_offset) else {
86 return None;
87 };
88 let mut offset = 0;
89 while offset < bytes.len() {
90 data_out[offset] = MaybeUninit::new(bytes[offset]);
91 offset += 1;
92 }
93 Some(new_from)
94 }
95 else {
97 let Ok((len, mut from)) = take_array(from) else {
98 return None;
99 };
100 layout.len_layout.write(len as u32, len_out);
102 let Some((_, mut data_out)) = out.split_at_mut_checked(layout.data_offset) else {
103 return None;
104 };
105 let mut i = 0;
106 while i < len {
107 let Some(new_from) = deserialize_const_ptr(from, item_layout, data_out) else {
108 return None;
109 };
110 let Some((_, item_out)) = data_out.split_at_mut_checked(item_layout.size()) else {
111 return None;
112 };
113 data_out = item_out;
114 from = new_from;
115 i += 1;
116 }
117 Some(from)
118 }
119}