macro_rules! mav_scalar_ty {
(u8) => {
u8
};
(i8) => {
i8
};
(char) => {
u8
};
(u16) => {
u16
};
(i16) => {
i16
};
(u32) => {
u32
};
(i32) => {
i32
};
(f32) => {
f32
};
(u64) => {
u64
};
(i64) => {
i64
};
(f64) => {
f64
};
}
macro_rules! mav_scalar_size {
(u8) => {
1
};
(i8) => {
1
};
(char) => {
1
};
(u16) => {
2
};
(i16) => {
2
};
(u32) => {
4
};
(i32) => {
4
};
(f32) => {
4
};
(u64) => {
8
};
(i64) => {
8
};
(f64) => {
8
};
}
macro_rules! mav_scalar_str {
(u8) => {
"uint8_t"
};
(i8) => {
"int8_t"
};
(char) => {
"char"
};
(u16) => {
"uint16_t"
};
(i16) => {
"int16_t"
};
(u32) => {
"uint32_t"
};
(i32) => {
"int32_t"
};
(f32) => {
"float"
};
(u64) => {
"uint64_t"
};
(i64) => {
"int64_t"
};
(f64) => {
"double"
};
}
macro_rules! mav_scalar_zero {
(f32) => {
0.0
};
(f64) => {
0.0
};
($k:tt) => {
0
};
}
macro_rules! mav_field_zero {
([ $k:tt ; $n:literal ]) => {
[mav_scalar_zero!($k); $n]
};
($k:tt) => {
mav_scalar_zero!($k)
};
}
macro_rules! mav_field_ty {
([ $k:tt ; $n:literal ]) => {
[mav_scalar_ty!($k); $n]
};
($k:tt) => {
mav_scalar_ty!($k)
};
}
macro_rules! mav_field_size {
([ $k:tt ; $n:literal ]) => {
mav_scalar_size!($k) * $n
};
($k:tt) => {
mav_scalar_size!($k)
};
}
macro_rules! mav_scalar_kind {
(u8) => {
$crate::dialect::FieldType::U8
};
(i8) => {
$crate::dialect::FieldType::I8
};
(char) => {
$crate::dialect::FieldType::Char
};
(u16) => {
$crate::dialect::FieldType::U16
};
(i16) => {
$crate::dialect::FieldType::I16
};
(u32) => {
$crate::dialect::FieldType::U32
};
(i32) => {
$crate::dialect::FieldType::I32
};
(f32) => {
$crate::dialect::FieldType::F32
};
(u64) => {
$crate::dialect::FieldType::U64
};
(i64) => {
$crate::dialect::FieldType::I64
};
(f64) => {
$crate::dialect::FieldType::F64
};
}
macro_rules! mav_field_kind {
([ $k:tt ; $n:literal ]) => {
mav_scalar_kind!($k)
};
($k:tt) => {
mav_scalar_kind!($k)
};
}
macro_rules! mav_field_str {
([ $k:tt ; $n:literal ]) => {
mav_scalar_str!($k)
};
($k:tt) => {
mav_scalar_str!($k)
};
}
macro_rules! mav_field_arraylen {
([ $k:tt ; $n:literal ]) => {
$n
};
($k:tt) => {
0usize
};
}
macro_rules! mav_encode_field {
($out:ident, $off:ident, $value:expr, [ $k:tt ; $n:literal ]) => {{
let mut __i = 0usize;
while __i < $n {
let __bytes = $value[__i].to_le_bytes();
$out[$off..$off + __bytes.len()].copy_from_slice(&__bytes);
$off += __bytes.len();
__i += 1;
}
}};
($out:ident, $off:ident, $value:expr, $k:tt) => {{
let __bytes = $value.to_le_bytes();
$out[$off..$off + __bytes.len()].copy_from_slice(&__bytes);
$off += __bytes.len();
}};
}
macro_rules! mav_decode_field {
($buf:ident, $off:ident, [ $k:tt ; $n:literal ]) => {{
type __Elem = mav_scalar_ty!($k);
const __SZ: usize = mav_scalar_size!($k);
let mut __arr: [__Elem; $n] = [Default::default(); $n];
let mut __i = 0usize;
while __i < $n {
let __bytes: [u8; __SZ] = (&$buf[$off..$off + __SZ]).try_into().unwrap();
__arr[__i] = <__Elem>::from_le_bytes(__bytes);
$off += __SZ;
__i += 1;
}
__arr
}};
($buf:ident, $off:ident, $k:tt) => {{
type __Scalar = mav_scalar_ty!($k);
const __SZ: usize = mav_scalar_size!($k);
let __bytes: [u8; __SZ] = (&$buf[$off..$off + __SZ]).try_into().unwrap();
$off += __SZ;
<__Scalar>::from_le_bytes(__bytes)
}};
}
macro_rules! message {
(
$(#[$meta:meta])*
$struct:ident = $id:literal, crc = $crc:literal, name = $wire:literal;
$( $field:ident : $fty:tt ),+ $(,)?
$( ; ext { $( $efield:ident : $efty:tt ),+ $(,)? } )?
) => {
$(#[$meta])*
#[derive(Clone, Copy, Debug, PartialEq)]
#[allow(missing_docs)]
pub struct $struct {
$( pub $field: mav_field_ty!($fty), )+
$( $( pub $efield: mav_field_ty!($efty), )+ )?
}
impl $struct {
pub const fn zeroed() -> Self {
$struct {
$( $field: mav_field_zero!($fty), )+
$( $( $efield: mav_field_zero!($efty), )+ )?
}
}
}
impl Default for $struct {
fn default() -> Self {
Self::zeroed()
}
}
impl $crate::dialect::Message for $struct {
const ID: u32 = $id;
const NAME: &'static str = $wire;
const CRC_EXTRA: u8 = $crc;
const WIRE_LEN: usize =
0 $( + mav_field_size!($fty) )+ $( $( + mav_field_size!($efty) )+ )?;
const BASE_FIELDS: &'static [(&'static str, &'static str, u8)] = &[
$(
(
mav_field_str!($fty),
$crate::dialect::xml_name(stringify!($field)),
mav_field_arraylen!($fty) as u8,
),
)+
];
const DESCRIPTOR: &'static $crate::dialect::MessageDescriptor<'static> =
&$crate::dialect::MessageDescriptor {
id: $id,
name: $wire,
crc_extra: $crc,
fields: &[
$(
$crate::dialect::FieldDescriptor {
name: $crate::dialect::xml_name(stringify!($field)),
ty: mav_field_kind!($fty),
array_len: mav_field_arraylen!($fty) as u8,
extension: false,
},
)+
$($(
$crate::dialect::FieldDescriptor {
name: $crate::dialect::xml_name(stringify!($efield)),
ty: mav_field_kind!($efty),
array_len: mav_field_arraylen!($efty) as u8,
extension: true,
},
)+)?
],
};
fn encode(&self, out: &mut [u8]) -> usize {
let mut off = 0usize;
$( mav_encode_field!(out, off, self.$field, $fty); )+
$( $( mav_encode_field!(out, off, self.$efield, $efty); )+ )?
off
}
fn decode(payload: &[u8]) -> $crate::Result<Self> {
let mut buf = [0u8; Self::WIRE_LEN];
let n = core::cmp::min(payload.len(), Self::WIRE_LEN);
buf[..n].copy_from_slice(&payload[..n]);
let mut off = 0usize;
$( let $field = mav_decode_field!(buf, off, $fty); )+
$( $( let $efield = mav_decode_field!(buf, off, $efty); )+ )?
let _ = off;
Ok($struct { $( $field, )+ $( $( $efield, )+ )? })
}
}
};
}