12
12
13
13
/// Implements serialization for a single TLV record.
14
14
/// This is exported for use by other exported macros, do not use directly.
15
+ #[ doc( hidden) ]
15
16
#[ macro_export]
16
17
macro_rules! _encode_tlv {
17
18
( $stream: expr, $type: expr, $field: expr, ( default_value, $default: expr) ) => {
@@ -41,6 +42,42 @@ macro_rules! _encode_tlv {
41
42
}
42
43
43
44
/// Implements the TLVs serialization part in a Writeable implementation of a struct.
45
+ ///
46
+ /// This should be called inside a method which returns `Result<_, `[`io::Error`]`>`, such as
47
+ /// [`Writeable::write`]. It will only return an `Err` if the stream `Err`s or [`Writeable::write`]
48
+ /// on one of the fields `Err`s.
49
+ ///
50
+ /// `$stream` must be a `&mut `[`Writer`] which will receive the bytes for each TLV in the stream.
51
+ ///
52
+ /// Fields MUST be sorted in `$type`-order.
53
+ ///
54
+ /// Note that the lightning TLV requirements require that a single type not appear more than once,
55
+ /// that TLVs are sorted in type-ascending order, and that any even types be understood by the
56
+ /// decoder.
57
+ ///
58
+ /// Any `option` fields which have a value of `None` will not be serialized at all.
59
+ ///
60
+ /// For example,
61
+ /// ```
62
+ /// # use lightning::encode_tlv_stream;
63
+ /// # fn write<W: lightning::util::ser::Writer> (stream: &mut W) -> Result<(), lightning::io::Error> {
64
+ /// let mut required_value = 0u64;
65
+ /// let mut optional_value: Option<u64> = None;
66
+ /// encode_tlv_stream!(stream, {
67
+ /// (0, required_value, required),
68
+ /// (1, Some(42u64), option),
69
+ /// (2, optional_value, option),
70
+ /// });
71
+ /// // At this point `required_value` has been written as a TLV of type 0, `42u64` has been written
72
+ /// // as a TLV of type 1 (indicating the reader may ignore it if it is not understood), and *no*
73
+ /// // TLV is written with type 2.
74
+ /// # Ok(())
75
+ /// # }
76
+ /// ```
77
+ ///
78
+ /// [`io::Error`]: crate::io::Error
79
+ /// [`Writeable::write`]: crate::util::ser::Writeable::write
80
+ /// [`Writer`]: crate::util::ser::Writer
44
81
#[ macro_export]
45
82
macro_rules! encode_tlv_stream {
46
83
( $stream: expr, { $( ( $type: expr, $field: expr, $fieldty: tt) ) ,* $( , ) * } ) => { {
@@ -72,6 +109,7 @@ macro_rules! encode_tlv_stream {
72
109
73
110
/// Adds the length of the serialized field to a LengthCalculatingWriter.
74
111
/// This is exported for use by other exported macros, do not use directly.
112
+ #[ doc( hidden) ]
75
113
#[ macro_export]
76
114
macro_rules! _get_varint_length_prefixed_tlv_length {
77
115
( $len: expr, $type: expr, $field: expr, ( default_value, $default: expr) ) => {
@@ -98,6 +136,7 @@ macro_rules! _get_varint_length_prefixed_tlv_length {
98
136
99
137
/// See the documentation of write_tlv_fields!().
100
138
/// This is exported for use by other exported macros, do not use directly.
139
+ #[ doc( hidden) ]
101
140
#[ macro_export]
102
141
macro_rules! _encode_varint_length_prefixed_tlv {
103
142
( $stream: expr, { $( ( $type: expr, $field: expr, $fieldty: tt) ) ,* } ) => { {
@@ -117,6 +156,7 @@ macro_rules! _encode_varint_length_prefixed_tlv {
117
156
118
157
/// Errors if there are missing required TLV types between the last seen type and the type currently being processed.
119
158
/// This is exported for use by other exported macros, do not use directly.
159
+ #[ doc( hidden) ]
120
160
#[ macro_export]
121
161
macro_rules! _check_tlv_order {
122
162
( $last_seen_type: expr, $typ: expr, $type: expr, $field: ident, ( default_value, $default: expr) ) => { {
@@ -152,6 +192,7 @@ macro_rules! _check_tlv_order {
152
192
153
193
/// Errors if there are missing required TLV types after the last seen type.
154
194
/// This is exported for use by other exported macros, do not use directly.
195
+ #[ doc( hidden) ]
155
196
#[ macro_export]
156
197
macro_rules! _check_missing_tlv {
157
198
( $last_seen_type: expr, $type: expr, $field: ident, ( default_value, $default: expr) ) => { {
@@ -187,6 +228,7 @@ macro_rules! _check_missing_tlv {
187
228
188
229
/// Implements deserialization for a single TLV record.
189
230
/// This is exported for use by other exported macros, do not use directly.
231
+ #[ doc( hidden) ]
190
232
#[ macro_export]
191
233
macro_rules! _decode_tlv {
192
234
( $reader: expr, $field: ident, ( default_value, $default: expr) ) => { {
@@ -221,17 +263,59 @@ macro_rules! _decode_tlv {
221
263
222
264
/// Implements the TLVs deserialization part in a Readable implementation of a struct.
223
265
///
266
+ /// This should be called inside a method which returns `Result<_, `[`DecodeError`]`>`, such as
267
+ /// [`Readable::read`]. It will either return an `Err` or ensure all `required` fields have been
268
+ /// read and optionally read `optional` fields.
269
+ ///
270
+ /// `$stream` must be a [`Read`] and will be fully consumed, reading until no more bytes remain
271
+ /// (i.e. it returns [`DecodeError::ShortRead`]).
272
+ ///
273
+ /// Fields MUST be sorted in `$type`-order.
274
+ ///
275
+ /// Note that the lightning TLV requirements require that a single type not appear more than once,
276
+ /// that TLVs are sorted in type-ascending order, and that any even types be understood by the
277
+ /// decoder.
278
+ ///
279
+ /// For example,
280
+ /// ```
281
+ /// # use lightning::decode_tlv_stream;
282
+ /// # fn read<R: lightning::io::Read> (stream: R) -> Result<(), lightning::ln::msgs::DecodeError> {
283
+ /// let mut required_value = 0u64;
284
+ /// let mut optional_value: Option<u64> = None;
285
+ /// decode_tlv_stream!(stream, {
286
+ /// (0, required_value, required),
287
+ /// (2, optional_value, option),
288
+ /// });
289
+ /// // At this point, `required_value` has been overwritten with the TLV with type 0.
290
+ /// // `optional_value` may have been overwritten, setting it to `Some` if a TLV with type 2 was
291
+ /// // present.
292
+ /// # Ok(())
293
+ /// # }
294
+ /// ```
295
+ ///
296
+ /// [`DecodeError`]: crate::ln::msgs::DecodeError
297
+ /// [`Readable::read`]: crate::util::ser::Readable::read
298
+ /// [`Read`]: crate::io::Read
299
+ /// [`DecodeError::ShortRead`]: crate::ln::msgs::DecodeError::ShortRead
300
+ #[ macro_export]
301
+ macro_rules! decode_tlv_stream {
302
+ ( $stream: expr, { $( ( $type: expr, $field: ident, $fieldty: tt) ) ,* $( , ) * } ) => {
303
+ let rewind = |_, _| { unreachable!( ) } ;
304
+ $crate:: _decode_tlv_stream_range!( $stream, .., rewind, { $( ( $type, $field, $fieldty) ) ,* } ) ;
305
+ }
306
+ }
307
+
308
+ /// Similar to [`decode_tlv_stream`] with a custom TLV decoding capabilities.
309
+ ///
224
310
/// `$decode_custom_tlv` is a closure that may be optionally provided to handle custom message types.
225
311
/// If it is provided, it will be called with the custom type and the `FixedLengthReader` containing
226
312
/// the message contents. It should return `Ok(true)` if the custom message is successfully parsed,
227
313
/// `Ok(false)` if the message type is unknown, and `Err(DecodeError)` if parsing fails.
228
- #[ macro_export]
229
- macro_rules! decode_tlv_stream {
314
+ macro_rules! decode_tlv_stream_with_custom_tlv_decode {
230
315
( $stream: expr, { $( ( $type: expr, $field: ident, $fieldty: tt) ) ,* $( , ) * }
231
316
$( , $decode_custom_tlv: expr) ?) => { {
232
317
let rewind = |_, _| { unreachable!( ) } ;
233
- use core:: ops:: RangeBounds ;
234
- $crate:: _decode_tlv_stream_range!(
318
+ _decode_tlv_stream_range!(
235
319
$stream, .., rewind, { $( ( $type, $field, $fieldty) ) ,* } $( , $decode_custom_tlv) ?
236
320
) ;
237
321
} }
@@ -242,6 +326,7 @@ macro_rules! decode_tlv_stream {
242
326
macro_rules! _decode_tlv_stream_range {
243
327
( $stream: expr, $range: expr, $rewind: ident, { $( ( $type: expr, $field: ident, $fieldty: tt) ) ,* $( , ) * }
244
328
$( , $decode_custom_tlv: expr) ?) => { {
329
+ use core:: ops:: RangeBounds ;
245
330
use $crate:: ln:: msgs:: DecodeError ;
246
331
let mut last_seen_type: Option <u64 > = None ;
247
332
let mut stream_ref = $stream;
@@ -434,6 +519,7 @@ macro_rules! read_tlv_fields {
434
519
435
520
/// Initializes the struct fields.
436
521
/// This is exported for use by other exported macros, do not use directly.
522
+ #[ doc( hidden) ]
437
523
#[ macro_export]
438
524
macro_rules! _init_tlv_based_struct_field {
439
525
( $field: ident, ( default_value, $default: expr) ) => {
@@ -452,6 +538,7 @@ macro_rules! _init_tlv_based_struct_field {
452
538
453
539
/// Initializes the variable we are going to read the TLV into.
454
540
/// This is exported for use by other exported macros, do not use directly.
541
+ #[ doc( hidden) ]
455
542
#[ macro_export]
456
543
macro_rules! _init_tlv_field_var {
457
544
( $field: ident, ( default_value, $default: expr) ) => {
0 commit comments