1#![allow(clippy::upper_case_acronyms)]
2use assembly_fdb_core::file::{FDBBucketHeader, FDBColumnHeader, FDBFieldData, FDBTableHeader};
5use std::convert::TryInto;
6
7#[derive(Copy, Clone)]
9pub struct FDBTableHeaderSlice<'a>(pub(super) &'a [u8]);
10
11fn read_table_header(buf: &[u8; 8]) -> FDBTableHeader {
12 let (a, b) = buf.split_at(4);
13 FDBTableHeader {
14 table_def_header_addr: u32::from_le_bytes(a.try_into().unwrap()),
15 table_data_header_addr: u32::from_le_bytes(b.try_into().unwrap()),
16 }
17}
18
19impl<'a> Iterator for FDBTableHeaderSlice<'a> {
20 type Item = FDBTableHeader;
21
22 fn next(&mut self) -> Option<Self::Item> {
23 if self.0.len() >= 8 {
24 let (next, rest) = self.0.split_at(8);
25 self.0 = rest;
26 let header = read_table_header(next.try_into().unwrap());
27 Some(header)
28 } else {
29 None
30 }
31 }
32}
33
34impl<'a> DoubleEndedIterator for FDBTableHeaderSlice<'a> {
35 fn next_back(&mut self) -> Option<Self::Item> {
36 let len = self.0.len();
37 if len >= 8 {
38 let (rest, next) = self.0.split_at(len - 8);
39 self.0 = rest;
40 let header = read_table_header(next.try_into().unwrap());
41 Some(header)
42 } else {
43 None
44 }
45 }
46}
47
48#[derive(Copy, Clone)]
50pub struct FDBColumnHeaderSlice<'a>(pub(super) &'a [u8]);
51
52fn read_column_header(buf: &[u8; 8]) -> FDBColumnHeader {
53 let (a, b) = buf.split_at(4);
54 FDBColumnHeader {
55 column_data_type: u32::from_le_bytes(a.try_into().unwrap()),
56 column_name_addr: u32::from_le_bytes(b.try_into().unwrap()),
57 }
58}
59
60impl<'a> FDBColumnHeaderSlice<'a> {
61 pub const fn len(&self) -> usize {
63 self.0.len() / std::mem::size_of::<FDBColumnHeader>()
64 }
65
66 pub const fn is_empty(&self) -> bool {
68 self.0.is_empty()
69 }
70}
71
72impl<'a> Iterator for FDBColumnHeaderSlice<'a> {
73 type Item = FDBColumnHeader;
74
75 fn next(&mut self) -> Option<Self::Item> {
76 if self.0.len() >= 8 {
77 let (next, rest) = self.0.split_at(8);
78 self.0 = rest;
79 let header = read_column_header(next.try_into().unwrap());
80 Some(header)
81 } else {
82 None
83 }
84 }
85}
86
87impl<'a> DoubleEndedIterator for FDBColumnHeaderSlice<'a> {
88 fn next_back(&mut self) -> Option<Self::Item> {
89 let len = self.0.len();
90 if len >= 8 {
91 let (rest, next) = self.0.split_at(len - 8);
92 self.0 = rest;
93 let header = read_column_header(next.try_into().unwrap());
94 Some(header)
95 } else {
96 None
97 }
98 }
99}
100
101#[derive(Copy, Clone)]
103pub struct FDBBucketHeaderSlice<'a>(pub(super) &'a [u8]);
104
105fn read_bucket_header(buf: &[u8; 4]) -> FDBBucketHeader {
106 FDBBucketHeader {
107 row_header_list_head_addr: u32::from_le_bytes(*buf),
108 }
109}
110
111impl<'a> Iterator for FDBBucketHeaderSlice<'a> {
112 type Item = FDBBucketHeader;
113
114 fn next(&mut self) -> Option<Self::Item> {
115 if self.0.len() >= 4 {
116 let (next, rest) = self.0.split_at(4);
117 self.0 = rest;
118 let header = read_bucket_header(next.try_into().unwrap());
119 Some(header)
120 } else {
121 None
122 }
123 }
124
125 fn nth(&mut self, n: usize) -> Option<Self::Item> {
126 let base = n * std::mem::size_of::<Self::Item>();
127 let next = base + std::mem::size_of::<Self::Item>();
128 if self.0.len() >= next {
129 let (_skipped, start) = self.0.split_at(base);
130 let (next, rest) = start.split_at(std::mem::size_of::<Self::Item>());
131 self.0 = rest;
132 Some(read_bucket_header(next.try_into().unwrap()))
133 } else {
134 self.0 = self.0.split_at(self.0.len()).1;
135 None
136 }
137 }
138}
139
140impl<'a> DoubleEndedIterator for FDBBucketHeaderSlice<'a> {
141 fn next_back(&mut self) -> Option<Self::Item> {
142 let len = self.0.len();
143 if len >= 4 {
144 let (rest, next) = self.0.split_at(len - 4);
145 self.0 = rest;
146 let header = read_bucket_header(next.try_into().unwrap());
147 Some(header)
148 } else {
149 None
150 }
151 }
152}
153
154#[derive(Copy, Clone)]
156pub struct FDBFieldDataSlice<'a>(pub(super) &'a [u8]);
157
158fn read_field_data(buf: &[u8; 8]) -> FDBFieldData {
159 let (a, b) = buf.split_at(4);
160 FDBFieldData {
161 data_type: u32::from_le_bytes(a.try_into().unwrap()),
162 value: b.try_into().unwrap(),
163 }
164}
165
166impl<'a> Iterator for FDBFieldDataSlice<'a> {
167 type Item = FDBFieldData;
168
169 fn next(&mut self) -> Option<Self::Item> {
170 if self.0.len() >= 8 {
171 let (next, rest) = self.0.split_at(8);
172 self.0 = rest;
173 let header = read_field_data(next.try_into().unwrap());
174 Some(header)
175 } else {
176 None
177 }
178 }
179}
180
181impl<'a> DoubleEndedIterator for FDBFieldDataSlice<'a> {
182 fn next_back(&mut self) -> Option<Self::Item> {
183 let len = self.0.len();
184 if len >= 8 {
185 let (rest, next) = self.0.split_at(len - 8);
186 self.0 = rest;
187 let header = read_field_data(next.try_into().unwrap());
188 Some(header)
189 } else {
190 None
191 }
192 }
193}