use crate::fdb::file::{FDBBucketHeader, FDBColumnHeader, FDBFieldData, FDBTableHeader};
use std::convert::TryInto;
#[derive(Copy, Clone)]
pub struct FDBTableHeaderSlice<'a>(pub(super) &'a [u8]);
fn read_table_header(buf: &[u8; 8]) -> FDBTableHeader {
let (a, b) = buf.split_at(4);
FDBTableHeader {
table_def_header_addr: u32::from_le_bytes(a.try_into().unwrap()),
table_data_header_addr: u32::from_le_bytes(b.try_into().unwrap()),
}
}
impl<'a> Iterator for FDBTableHeaderSlice<'a> {
type Item = FDBTableHeader;
fn next(&mut self) -> Option<Self::Item> {
if self.0.len() >= 8 {
let (next, rest) = self.0.split_at(8);
self.0 = rest;
let header = read_table_header(next.try_into().unwrap());
Some(header)
} else {
None
}
}
}
impl<'a> DoubleEndedIterator for FDBTableHeaderSlice<'a> {
fn next_back(&mut self) -> Option<Self::Item> {
let len = self.0.len();
if len >= 8 {
let (rest, next) = self.0.split_at(len - 8);
self.0 = rest;
let header = read_table_header(next.try_into().unwrap());
Some(header)
} else {
None
}
}
}
#[derive(Copy, Clone)]
pub struct FDBColumnHeaderSlice<'a>(pub(super) &'a [u8]);
fn read_column_header(buf: &[u8; 8]) -> FDBColumnHeader {
let (a, b) = buf.split_at(4);
FDBColumnHeader {
column_data_type: u32::from_le_bytes(a.try_into().unwrap()),
column_name_addr: u32::from_le_bytes(b.try_into().unwrap()),
}
}
impl<'a> Iterator for FDBColumnHeaderSlice<'a> {
type Item = FDBColumnHeader;
fn next(&mut self) -> Option<Self::Item> {
if self.0.len() >= 8 {
let (next, rest) = self.0.split_at(8);
self.0 = rest;
let header = read_column_header(next.try_into().unwrap());
Some(header)
} else {
None
}
}
}
impl<'a> DoubleEndedIterator for FDBColumnHeaderSlice<'a> {
fn next_back(&mut self) -> Option<Self::Item> {
let len = self.0.len();
if len >= 8 {
let (rest, next) = self.0.split_at(len - 8);
self.0 = rest;
let header = read_column_header(next.try_into().unwrap());
Some(header)
} else {
None
}
}
}
#[derive(Copy, Clone)]
pub struct FDBBucketHeaderSlice<'a>(pub(super) &'a [u8]);
fn read_bucket_header(buf: &[u8; 4]) -> FDBBucketHeader {
FDBBucketHeader {
row_header_list_head_addr: u32::from_le_bytes(*buf),
}
}
impl<'a> Iterator for FDBBucketHeaderSlice<'a> {
type Item = FDBBucketHeader;
fn next(&mut self) -> Option<Self::Item> {
if self.0.len() >= 4 {
let (next, rest) = self.0.split_at(4);
self.0 = rest;
let header = read_bucket_header(next.try_into().unwrap());
Some(header)
} else {
None
}
}
}
impl<'a> DoubleEndedIterator for FDBBucketHeaderSlice<'a> {
fn next_back(&mut self) -> Option<Self::Item> {
let len = self.0.len();
if len >= 4 {
let (rest, next) = self.0.split_at(len - 4);
self.0 = rest;
let header = read_bucket_header(next.try_into().unwrap());
Some(header)
} else {
None
}
}
}
#[derive(Copy, Clone)]
pub struct FDBFieldDataSlice<'a>(pub(super) &'a [u8]);
fn read_field_data(buf: &[u8; 8]) -> FDBFieldData {
let (a, b) = buf.split_at(4);
FDBFieldData {
data_type: u32::from_le_bytes(a.try_into().unwrap()),
value: b.try_into().unwrap(),
}
}
impl<'a> Iterator for FDBFieldDataSlice<'a> {
type Item = FDBFieldData;
fn next(&mut self) -> Option<Self::Item> {
if self.0.len() >= 8 {
let (next, rest) = self.0.split_at(8);
self.0 = rest;
let header = read_field_data(next.try_into().unwrap());
Some(header)
} else {
None
}
}
}
impl<'a> DoubleEndedIterator for FDBFieldDataSlice<'a> {
fn next_back(&mut self) -> Option<Self::Item> {
let len = self.0.len();
if len >= 8 {
let (rest, next) = self.0.split_at(len - 8);
self.0 = rest;
let header = read_field_data(next.try_into().unwrap());
Some(header)
} else {
None
}
}
}