make read_data internals work better

gui-branch
an 2019-04-01 03:37:59 -04:00
parent 36e11b95e8
commit dc899fa058
1 changed files with 60 additions and 57 deletions

View File

@ -5,101 +5,102 @@ use std::{fmt, num::NonZeroU16};
#[doc(hidden)]
#[macro_export]
macro_rules! _rd_impl {
// big endian
(BIG $b:expr; $nam:ident u16 $n:expr; $at:expr) => {
_rd_impl!($b; u16::from_be_bytes, $nam 2 $n + $at);
macro_rules! rd_impl {
// worker - creates let statement
(W $b:expr, $pth:path, $nam:ident, $n:expr) => {
let $nam = $pth([$b[$n], $b[$n + 1]]);
};
(BIG $b:expr; $nam:ident i16 $n:expr; $at:expr) => {
_rd_impl!($b; i16::from_be_bytes, $nam 2 $n + $at);
};
(BIG $b:expr; $nam:ident u32 $n:expr; $at:expr) => {
_rd_impl!($b; u32::from_be_bytes, $nam 4 $n + $at);
};
(BIG $b:expr; $nam:ident i32 $n:expr; $at:expr) => {
_rd_impl!($b; i32::from_be_bytes, $nam 4 $n + $at);
(D $b:expr, $pth:path, $nam:ident, $n:expr) => {
let $nam = $pth([$b[$n], $b[$n + 1], $b[$n + 2], $b[$n + 3]]);
};
(LITTLE $b:expr; $nam:ident u16 $n:expr; $at:expr) => {
_rd_impl!($b; u16::from_le_bytes, $nam 2 $n + $at);
// big endian
(BIG, $b:expr, $at:expr, $n:expr; $nam:ident, u16) => {
$crate::rd_impl!(W $b, u16::from_be_bytes, $nam, $n + $at);
};
(LITTLE $b:expr; $nam:ident i16 $n:expr; $at:expr) => {
_rd_impl!($b; i16::from_le_bytes, $nam 2 $n + $at);
(BIG, $b:expr, $at:expr, $n:expr; $nam:ident, i16) => {
$crate::rd_impl!(W $b, i16::from_be_bytes, $nam, $n + $at);
};
(LITTLE $b:expr; $nam:ident u32 $n:expr; $at:expr) => {
_rd_impl!($b; u32::from_le_bytes, $nam 4 $n + $at);
(BIG, $b:expr, $at:expr, $n:expr; $nam:ident, u32) => {
$crate::rd_impl!(D $b, u32::from_be_bytes, $nam, $n + $at);
};
(LITTLE $b:expr; $nam:ident i32 $n:expr; $at:expr) => {
_rd_impl!($b; i32::from_le_bytes, $nam 4 $n + $at);
(BIG, $b:expr, $at:expr, $n:expr; $nam:ident, i32) => {
$crate::rd_impl!(D $b, i32::from_be_bytes, $nam, $n + $at);
};
// little endian
(LITTLE, $b:expr, $at:expr, $n:expr; $nam:ident, u16) => {
$crate::rd_impl!(W $b, u16::from_le_bytes, $nam, $n + $at);
};
(LITTLE, $b:expr, $at:expr, $n:expr; $nam:ident, i16) => {
$crate::rd_impl!(W $b, i16::from_le_bytes, $nam, $n + $at);
};
(LITTLE, $b:expr, $at:expr, $n:expr; $nam:ident, u32) => {
$crate::rd_impl!(D $b, u32::from_le_bytes, $nam, $n + $at);
};
(LITTLE, $b:expr, $at:expr, $n:expr; $nam:ident, i32) => {
$crate::rd_impl!(D $b, i32::from_le_bytes, $nam, $n + $at);
};
// either endianness
($e:ident $b:expr; $nam:ident Angle $n:expr; $at:expr) => {
_rd_impl!($e $b; $nam u16 $n; $at);
($e:ident, $b:expr, $at:expr, $n:expr; $nam:ident, Angle) => {
$crate::rd_impl!($e, $b, $at, $n; $nam, u16);
let $nam = Angle::from_bits($nam);
};
($e:ident $b:expr; $nam:ident Fixed $n:expr; $at:expr) => {
_rd_impl!($e $b; $nam u32 $n; $at);
($e:ident, $b:expr, $at:expr, $n:expr; $nam:ident, Fixed) => {
$crate::rd_impl!($e, $b, $at, $n; $nam, u32);
let $nam = Fixed::from_bits($nam);
};
($e:ident $b:expr; $nam:ident Unit $n:expr; $at:expr) => {
_rd_impl!($e $b; $nam u16 $n; $at);
($e:ident, $b:expr, $at:expr, $n:expr; $nam:ident, Unit) => {
$crate::rd_impl!($e, $b, $at, $n; $nam, u16);
let $nam = Unit::from_bits($nam);
};
($e:ident $b:expr; $nam:ident OptU16 $n:expr; $at:expr) => {
_rd_impl!($e $b; $nam u16 $n; $at);
($e:ident, $b:expr, $at:expr, $n:expr; $nam:ident, OptU16) => {
$crate::rd_impl!($e, $b, $at, $n; $nam, u16);
let $nam = OptU16::from($nam);
};
($e:ident $b:expr; $nam:ident usize u16 $n:expr; $at:expr) => {
_rd_impl!($e $b; $nam u16 $n; $at);
($e:ident, $b:expr, $at:expr, $n:expr; $nam:ident, usize, u16) => {
$crate::rd_impl!($e, $b, $at, $n; $nam, u16);
let $nam = usize::from($nam);
};
($e:ident $b:expr; $nam:ident usize u32 $n:expr; $at:expr) => {
_rd_impl!($e $b; $nam u32 $n; $at);
($e:ident, $b:expr, $at:expr, $n:expr; $nam:ident, usize, u32) => {
$crate::rd_impl!($e, $b, $at, $n; $nam, u32);
let $nam = usize_from_u32($nam);
};
(
$e:ident $b:expr; $nam:ident enum $et:ident $t:ident $n:expr; $at:expr
($e:ident, $b:expr, $at:expr, $n:expr;
$nam:ident, enum, $et:ident, $t:ident
) => {
_rd_impl!($e $b; $nam $t $n; $at);
$crate::rd_impl!($e, $b, $at, $n; $nam, $t);
let $nam = $et::try_from($nam)?;
};
(
$e:ident $b:expr; $nam:ident flag $ft:ident $t:ident $n:expr; $at:expr
($e:ident, $b:expr, $at:expr, $n:expr;
$nam:ident, flag, $ft:ident, $t:ident
) => {
_rd_impl!($e $b; $nam $t $n; $at);
$crate::rd_impl!($e, $b, $at, $n; $nam, $t);
let $nam = flag_ok!($ft, $nam)?;
};
// no endianness
($_:ident $b:expr; $nam:ident u8 $n:expr; $at:expr) => {
($_:ident, $b:expr, $at:expr, $n:expr; $nam:ident, u8) => {
let $nam = $b[$n + $at];
};
($_:ident $b:expr; $nam:ident i8 $n:expr; $at:expr) => {
($_:ident, $b:expr, $at:expr, $n:expr; $nam:ident, i8) => {
let $nam = $b[$n + $at] as i8;
};
($_:ident $b:expr; $nam:ident u8 $n:expr; $rn:expr; $at:expr) => {
($_:ident, $b:expr, $at:expr, $n:expr; $rn:expr; $nam:ident, u8) => {
let $nam = &$b[$n + $at..$n + $at + $rn];
};
($_:ident $b:expr; $nam:ident Ident $n:expr; $at:expr) => {
_rd_impl!($b; Ident, $nam 4 $n + $at);
($_:ident, $b:expr, $at:expr, $n:expr; $nam:ident, Ident) => {
$crate::rd_impl!(D $b, Ident, $nam, $n + $at);
};
(
$_:ident $b:expr; $nam:ident no_try $f:ident $n:expr; $rn:expr; $at:expr
($_:ident, $b:expr, $at:expr, $n:expr; $rn:expr;
$nam:ident, no_try, $f:expr
) => {
let $nam = $f(&$b[$n + $at..$n + $at + $rn]);
};
($_:ident $b:expr; $nam:ident $f:ident $n:expr; $rn:expr; $at:expr) => {
($_:ident, $b:expr, $at:expr, $n:expr; $rn:expr; $nam:ident, $f:expr) => {
let $nam = $f(&$b[$n + $at..$n + $at + $rn])?;
};
// worker - creates let statement
($b:expr; $pth:path , $nam:ident 2 $n:expr) => {
let $nam = $pth([$b[$n], $b[$n + 1]]);
};
($b:expr; $pth:path , $nam:ident 4 $n:expr) => {
let $nam = $pth([$b[$n], $b[$n + 1], $b[$n + 2], $b[$n + 3]]);
};
}
/// Reads structured data from a byte slice.
@ -183,12 +184,14 @@ macro_rules! _rd_impl {
#[macro_export]
macro_rules! read_data {
(
endian: $ty:ident, buf: $b:expr, size: $sz:expr, start: $at:expr, data {
$(let $nam:ident = $t:ident[$n:expr $(; $rn:expr)?] $($ex:ident)*;)*
endian: $e:ident, buf: $b:expr, size: $sz:expr, start: $at:expr, data {
$(let $nam:ident = $t:ident$(::$tc:ident)*[$n:expr $(; $rn:expr)?]
$($ex:ident)*;)*
}
) => {
$crate::check_data!($at + $sz, $b);
$($crate::_rd_impl!($ty $b; $nam $($ex)* $t ($n); $(($rn);)? ($at));)*
$($crate::rd_impl!($e, $b, $at, $n;
$($rn;)? $nam, $($ex,)* $t$(::$tc)*);)*
};
}