use assembly_fdb_core::file::*;
use nom::{
bytes::complete::take, combinator::map, number::complete::le_u32, sequence::tuple, IResult,
};
use std::convert::TryInto;
fn u8_4(i: &[u8]) -> IResult<&[u8], [u8; 4]> {
let (i, slice) = take(4usize)(i)?;
Ok((i, slice.try_into().unwrap()))
}
#[allow(clippy::upper_case_acronyms)]
pub trait ParseLE: Sized + Copy {
const BYTE_COUNT: usize;
type Buf: AsMut<[u8]> + Default;
fn parse(i: &[u8]) -> IResult<&[u8], Self>;
}
impl ParseLE for u32 {
const BYTE_COUNT: usize = 4;
type Buf = [u8; 4];
fn parse(input: &[u8]) -> IResult<&[u8], u32> {
le_u32(input)
}
}
impl ParseLE for (u32, u32) {
const BYTE_COUNT: usize = 8;
type Buf = [u8; 8];
fn parse(input: &[u8]) -> IResult<&[u8], (u32, u32)> {
tuple((le_u32, le_u32))(input)
}
}
impl ParseLE for (u32, [u8; 4]) {
const BYTE_COUNT: usize = 8;
type Buf = [u8; 8];
fn parse(input: &[u8]) -> IResult<&[u8], (u32, [u8; 4])> {
tuple((le_u32, u8_4))(input)
}
}
impl ParseLE for (u32, u32, u32) {
const BYTE_COUNT: usize = 12;
type Buf = [u8; 12];
fn parse(input: &[u8]) -> IResult<&[u8], (u32, u32, u32)> {
tuple((le_u32, le_u32, le_u32))(input)
}
}
#[allow(clippy::upper_case_acronyms)]
pub trait ParseFDB: Sized + Copy {
type IO: ParseLE;
fn new(i: Self::IO) -> Self;
fn parse(input: &[u8]) -> IResult<&[u8], Self> {
map(Self::IO::parse, Self::new)(input)
}
}
impl ParseFDB for ArrayHeader {
type IO = (u32, u32);
fn new((a, b): Self::IO) -> Self {
ArrayHeader {
count: a,
base_offset: b,
}
}
}
impl ParseFDB for FDBTableDefHeader {
type IO = (u32, u32, u32);
fn new((a, b, c): Self::IO) -> Self {
FDBTableDefHeader {
column_count: a,
table_name_addr: b,
column_header_list_addr: c,
}
}
}
impl ParseFDB for FDBTableDataHeader {
type IO = (u32, u32);
fn new((a, b): Self::IO) -> Self {
FDBTableDataHeader {
buckets: ArrayHeader::new((a, b)),
}
}
}
impl ParseFDB for FDBColumnHeader {
type IO = (u32, u32);
fn new((a, b): Self::IO) -> Self {
FDBColumnHeader {
column_data_type: a,
column_name_addr: b,
}
}
}
impl ParseFDB for FDBRowHeaderListEntry {
type IO = (u32, u32);
fn new((a, b): Self::IO) -> Self {
FDBRowHeaderListEntry {
row_header_addr: a,
row_header_list_next_addr: b,
}
}
}
impl ParseFDB for FDBRowHeader {
type IO = (u32, u32);
fn new(io: Self::IO) -> Self {
FDBRowHeader {
fields: ArrayHeader::from(io),
}
}
}
impl ParseFDB for FDBTableHeader {
type IO = (u32, u32);
fn new((a, b): Self::IO) -> Self {
FDBTableHeader {
table_def_header_addr: a,
table_data_header_addr: b,
}
}
}
impl ParseFDB for FDBHeader {
type IO = (u32, u32);
fn new((a, b): Self::IO) -> Self {
FDBHeader {
tables: ArrayHeader::from((a, b)),
}
}
}
impl ParseFDB for FDBBucketHeader {
type IO = u32;
fn new(a: Self::IO) -> Self {
FDBBucketHeader {
row_header_list_head_addr: a,
}
}
}
impl ParseFDB for FDBFieldData {
type IO = (u32, [u8; 4]);
fn new((data_type, value): Self::IO) -> Self {
FDBFieldData { data_type, value }
}
}