Skip to content

Commit

Permalink
Expose impl_writeable_msg
Browse files Browse the repository at this point in the history
  • Loading branch information
tnull committed Jan 21, 2023
1 parent 153b048 commit 8e41db0
Showing 1 changed file with 44 additions and 5 deletions.
49 changes: 44 additions & 5 deletions lightning/src/util/ser_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,20 +457,59 @@ macro_rules! _decode_tlv_stream_range {
} }
}

/// Implements [`Readable`]/[`Writeable`] for a message struct that may include non-TLV and
/// TLV-encoded parts.
///
/// This is useful to implement a [`CustomMessageReader`].
///
/// If `$fieldty` is `required`, then `$tlvfield` is a required field that is not an [`Option`] nor a [`Vec`].
/// If `$fieldty` is `(default_value, $default)`, then `$tlvfield` will be set to `$default` if not present.
/// If `$fieldty` is `option`, then `$tlvfield` is optional field.
/// If `$fieldty` is `vec_type`, then `$tlvfield` is a [`Vec`], which needs to have its individual elements serialized.
///
/// For example,
/// ```
/// # use lightning::impl_writeable_msg;
/// struct MyCustomMessage {
/// pub field_1: u32,
/// pub field_2: bool,
/// pub field_3: String,
/// pub tlv_integer: u32,
/// pub tlv_default_integer: u32,
/// pub tlv_optional_integer: Option<u32>,
/// pub tlv_vec_type_integer: Vec<u32>,
/// }
///
/// impl_writeable_msg!(MyCustomMessage, {
/// field_1,
/// field_2,
/// field_3
/// }, {
/// (0, tlv_integer, required),
/// (1, tlv_default_integer, (default_value, 7)),
/// (2, tlv_optional_integer, option),
/// (3, tlv_vec_type_integer, vec_type),
/// });
/// ```
///
/// [`Readable`]: crate::util::ser::Readable
/// [`Writeable`]: crate::util::ser::Writeable
/// [`CustomMessageReader`]: crate::ln::wire::CustomMessageReader
#[macro_export]
macro_rules! impl_writeable_msg {
($st:ident, {$($field:ident),* $(,)*}, {$(($type: expr, $tlvfield: ident, $fieldty: tt)),* $(,)*}) => {
impl $crate::util::ser::Writeable for $st {
fn write<W: $crate::util::ser::Writer>(&self, w: &mut W) -> Result<(), $crate::io::Error> {
$( self.$field.write(w)?; )*
encode_tlv_stream!(w, {$(($type, self.$tlvfield, $fieldty)),*});
$crate::encode_tlv_stream!(w, {$(($type, self.$tlvfield, $fieldty)),*});
Ok(())
}
}
impl $crate::util::ser::Readable for $st {
fn read<R: $crate::io::Read>(r: &mut R) -> Result<Self, $crate::ln::msgs::DecodeError> {
$(let $field = $crate::util::ser::Readable::read(r)?;)*
$(_init_tlv_field_var!($tlvfield, $fieldty);)*
decode_tlv_stream!(r, {$(($type, $tlvfield, $fieldty)),*});
$($crate::_init_tlv_field_var!($tlvfield, $fieldty);)*
$crate::decode_tlv_stream!(r, {$(($type, $tlvfield, $fieldty)),*});
Ok(Self {
$($field),*,
$($tlvfield),*
Expand Down Expand Up @@ -642,10 +681,10 @@ macro_rules! _init_and_read_tlv_fields {
}

/// 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 `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.
/// If `$fieldty` is `option`, then `$field` is optional field.
/// If `$fieldty` is `vec_type`, then `$field` is a Vec, which needs to have its individual elements serialized.
/// If `$fieldty` is `vec_type`, then `$field` is a [`Vec`], which needs to have its individual elements serialized.
///
/// For example,
/// ```
Expand Down

0 comments on commit 8e41db0

Please sign in to comment.