I'm implementing writing TLV packet to somewhat impl std::io::Write
.
First I implement WriteBE<T>
trait, whose write_be(&mut self, data: T)
method can write data with type T
to Self
. (implementation details omitted)
And I'm trying to use macro_rules! to implement calculation of total packet length in compile time (because most packets have fixed length in my case). macros are as follows:
macro_rules! len_in_expr {
(
self.write_be( $data: expr $(,)? ) $(?)? $(;)*
) => {
std::mem::size_of_val(&$data)
};
(
write_be(self, $data: expr $(,)? ) $(?)? $(;)*
) => {
std::mem::size_of_val(&$data)
};
(
$other: expr
) => {
0
};
}
/// calculate total write size in block
macro_rules! tlv_len_in_block {
({
$( $e: expr );* $(;)?
}) => {
0 $(
+ ( len_in_expr!($e) )
)*
};
}
But when I calculating total length like this:
fn main() {
let y = tlv_len_in_block!({
write_be(self, 0u32,)?;
});
println!("y={}", y);
}
I get a result 0
.
If I comment the $other: expr
match arm, I get a compile error:
6 | macro_rules! len_in_expr {
| ------------------------ when calling this macro
...
30 | + ( len_in_expr!($e) )
| ^^ no rules expected this token in macro call
...
39 | let y = tlv_len_in_block!({
| _____________-
40 | | write_be(self, 0u32,)?;
41 | | });
| |______- in this macro invocation
What's the problem with my code? And how can I fix it?