X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Fser_macros.rs;h=247fdf60074dc4ff0bad148bef3c89ae374f26d6;hb=2e33acbd9c5ebd605829859a982822df6e0f1723;hp=41185b179ffa815fee9d785fab9c18a2ab1711da;hpb=9e4a35a60d96930c73538e960e48209ac535e7ab;p=rust-lightning diff --git a/lightning/src/util/ser_macros.rs b/lightning/src/util/ser_macros.rs index 41185b17..247fdf60 100644 --- a/lightning/src/util/ser_macros.rs +++ b/lightning/src/util/ser_macros.rs @@ -143,6 +143,9 @@ macro_rules! encode_tlv_stream { #[macro_export] macro_rules! _encode_tlv_stream { ($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt)),* $(,)*}) => { { + $crate::_encode_tlv_stream!($stream, { $(($type, $field, $fieldty)),* }, &[]) + } }; + ($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt)),* $(,)*}, $extra_tlvs: expr) => { { #[allow(unused_imports)] use $crate::{ ln::msgs::DecodeError, @@ -154,6 +157,10 @@ macro_rules! _encode_tlv_stream { $( $crate::_encode_tlv!($stream, $type, $field, $fieldty); )* + for tlv in $extra_tlvs { + let (typ, value): &(u64, Vec) = tlv; + $crate::_encode_tlv!($stream, *typ, *value, required_vec); + } #[allow(unused_mut, unused_variables, unused_assignments)] #[cfg(debug_assertions)] @@ -162,18 +169,8 @@ macro_rules! _encode_tlv_stream { $( $crate::_check_encoded_tlv_order!(last_seen, $type, $fieldty); )* - } - } }; - ($stream: expr, $tlvs: expr) => { { - for tlv in $tlvs { - let (typ, value): &&(u64, Vec) = tlv; - $crate::_encode_tlv!($stream, *typ, *value, required_vec); - } - - #[cfg(debug_assertions)] { - let mut last_seen: Option = None; - for tlv in $tlvs { - let (typ, _): &&(u64, Vec) = tlv; + for tlv in $extra_tlvs { + let (typ, _): &(u64, Vec) = tlv; $crate::_check_encoded_tlv_order!(last_seen, *typ, required_vec); } } @@ -234,9 +231,10 @@ macro_rules! _get_varint_length_prefixed_tlv_length { #[macro_export] macro_rules! _encode_varint_length_prefixed_tlv { ($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt)),*}) => { { - _encode_varint_length_prefixed_tlv!($stream, {$(($type, $field, $fieldty)),*}, &[]) + $crate::_encode_varint_length_prefixed_tlv!($stream, {$(($type, $field, $fieldty)),*}, &[]) } }; ($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt)),*}, $extra_tlvs: expr) => { { + extern crate alloc; use $crate::util::ser::BigSize; use alloc::vec::Vec; let len = { @@ -246,14 +244,13 @@ macro_rules! _encode_varint_length_prefixed_tlv { $crate::_get_varint_length_prefixed_tlv_length!(len, $type, $field, $fieldty); )* for tlv in $extra_tlvs { - let (typ, value): &&(u64, Vec) = tlv; + let (typ, value): &(u64, Vec) = tlv; $crate::_get_varint_length_prefixed_tlv_length!(len, *typ, *value, required_vec); } len.0 }; BigSize(len as u64).write($stream)?; - $crate::_encode_tlv_stream!($stream, { $(($type, $field, $fieldty)),* }); - $crate::_encode_tlv_stream!($stream, $extra_tlvs); + $crate::_encode_tlv_stream!($stream, { $(($type, $field, $fieldty)),* }, $extra_tlvs); } }; } @@ -794,10 +791,13 @@ macro_rules! _init_tlv_field_var { /// Equivalent to running [`_init_tlv_field_var`] then [`read_tlv_fields`]. /// +/// If any unused values are read, their type MUST be specified or else `rustc` will read them as an +/// `i64`. +/// /// This is exported for use by other exported macros, do not use directly. #[doc(hidden)] #[macro_export] -macro_rules! _init_and_read_tlv_fields { +macro_rules! _init_and_read_len_prefixed_tlv_fields { ($reader: ident, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => { $( $crate::_init_tlv_field_var!($field, $fieldty); @@ -809,6 +809,22 @@ macro_rules! _init_and_read_tlv_fields { } } +/// Equivalent to running [`_init_tlv_field_var`] then [`decode_tlv_stream`]. +/// +/// If any unused values are read, their type MUST be specified or else `rustc` will read them as an +/// `i64`. +macro_rules! _init_and_read_tlv_stream { + ($reader: ident, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => { + $( + $crate::_init_tlv_field_var!($field, $fieldty); + )* + + $crate::decode_tlv_stream!($reader, { + $(($type, $field, $fieldty)),* + }); + } +} + /// Implements [`Readable`]/[`Writeable`] for a struct storing it as a set of TLVs /// If `$fieldty` is `required`, then `$field` is a required field that is not an [`Option`] nor a [`Vec`]. /// If `$fieldty` is `(default_value, $default)`, then `$field` will be set to `$default` if not present. @@ -818,8 +834,7 @@ macro_rules! _init_and_read_tlv_fields { /// /// For example, /// ``` -/// # use lightning::{impl_writeable_tlv_based, _encode_varint_length_prefixed_tlv}; -/// # extern crate alloc; +/// # use lightning::impl_writeable_tlv_based; /// struct LightningMessage { /// tlv_integer: u32, /// tlv_default_integer: u32, @@ -867,7 +882,7 @@ macro_rules! impl_writeable_tlv_based { impl $crate::util::ser::Readable for $st { fn read(reader: &mut R) -> Result { - $crate::_init_and_read_tlv_fields!(reader, { + $crate::_init_and_read_len_prefixed_tlv_fields!(reader, { $(($type, $field, $fieldty)),* }); Ok(Self { @@ -1019,7 +1034,7 @@ macro_rules! impl_writeable_tlv_based_enum { // Because read_tlv_fields creates a labeled loop, we cannot call it twice // in the same function body. Instead, we define a closure and call it. let f = || { - $crate::_init_and_read_tlv_fields!(reader, { + $crate::_init_and_read_len_prefixed_tlv_fields!(reader, { $(($type, $field, $fieldty)),* }); Ok($st::$variant_name { @@ -1073,7 +1088,7 @@ macro_rules! impl_writeable_tlv_based_enum_upgradable { // Because read_tlv_fields creates a labeled loop, we cannot call it twice // in the same function body. Instead, we define a closure and call it. let f = || { - $crate::_init_and_read_tlv_fields!(reader, { + $crate::_init_and_read_len_prefixed_tlv_fields!(reader, { $(($type, $field, $fieldty)),* }); Ok(Some($st::$variant_name {