Historically, we used `vec_type` for all TLV Vec reads/writes, but
it is asymmetric and thus somewhat confusing - on the write side it
always writes a TLV entry, even if there are zero elements. On the
read side, it happily accepts a missing TLV, providing a
zero-length vector.
In
85b573ddad70f3c5ee36e0992d587842af507a8d a new `optional_vec`
TLV format was added which was symmetric, but only supports
optional vecs. This adds the corresponding required form, always
writing a TLV and ensuring it is present.
BigSize($field.serialized_length() as u64).write($stream)?;
$field.write($stream)?;
};
BigSize($field.serialized_length() as u64).write($stream)?;
$field.write($stream)?;
};
+ ($stream: expr, $type: expr, $field: expr, required_vec) => {
+ $crate::_encode_tlv!($stream, $type, $crate::util::ser::WithoutLength(&$field), required);
+ };
($stream: expr, $type: expr, $field: expr, vec_type) => {
$crate::_encode_tlv!($stream, $type, $crate::util::ser::WithoutLength(&$field), required);
};
($stream: expr, $type: expr, $field: expr, vec_type) => {
$crate::_encode_tlv!($stream, $type, $crate::util::ser::WithoutLength(&$field), required);
};
};
($stream: expr, $type: expr, $field: expr, optional_vec) => {
if !$field.is_empty() {
};
($stream: expr, $type: expr, $field: expr, optional_vec) => {
if !$field.is_empty() {
- $crate::_encode_tlv!($stream, $type, $field, vec_type);
+ $crate::_encode_tlv!($stream, $type, $field, required_vec);
}
};
($stream: expr, $type: expr, $field: expr, upgradable_required) => {
}
};
($stream: expr, $type: expr, $field: expr, upgradable_required) => {
BigSize(field_len as u64).write(&mut $len).expect("No in-memory data may fail to serialize");
$len.0 += field_len;
};
BigSize(field_len as u64).write(&mut $len).expect("No in-memory data may fail to serialize");
$len.0 += field_len;
};
+ ($len: expr, $type: expr, $field: expr, required_vec) => {
+ $crate::_get_varint_length_prefixed_tlv_length!($len, $type, $crate::util::ser::WithoutLength(&$field), required);
+ };
($len: expr, $type: expr, $field: expr, vec_type) => {
$crate::_get_varint_length_prefixed_tlv_length!($len, $type, $crate::util::ser::WithoutLength(&$field), required);
};
($len: expr, $type: expr, $field: expr, vec_type) => {
$crate::_get_varint_length_prefixed_tlv_length!($len, $type, $crate::util::ser::WithoutLength(&$field), required);
};
};
($len: expr, $type: expr, $field: expr, optional_vec) => {
if !$field.is_empty() {
};
($len: expr, $type: expr, $field: expr, optional_vec) => {
if !$field.is_empty() {
- $crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, vec_type);
+ $crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, required_vec);
}
};
($len: expr, $type: expr, $field: expr, (option: $trait: ident $(, $read_arg: expr)?)) => {
}
};
($len: expr, $type: expr, $field: expr, (option: $trait: ident $(, $read_arg: expr)?)) => {
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, option) => {{
// no-op
}};
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, option) => {{
// no-op
}};
+ ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, required_vec) => {{
+ $crate::_check_decoded_tlv_order!($last_seen_type, $typ, $type, $field, required);
+ }};
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, vec_type) => {{
// no-op
}};
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, vec_type) => {{
// no-op
}};
($last_seen_type: expr, $type: expr, $field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {{
$crate::_check_missing_tlv!($last_seen_type, $type, $field, required);
}};
($last_seen_type: expr, $type: expr, $field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {{
$crate::_check_missing_tlv!($last_seen_type, $type, $field, required);
}};
+ ($last_seen_type: expr, $type: expr, $field: ident, required_vec) => {{
+ $crate::_check_missing_tlv!($last_seen_type, $type, $field, required);
+ }};
($last_seen_type: expr, $type: expr, $field: ident, vec_type) => {{
// no-op
}};
($last_seen_type: expr, $type: expr, $field: ident, vec_type) => {{
// no-op
}};
($reader: expr, $field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {{
$field = $trait::read(&mut $reader $(, $read_arg)*)?;
}};
($reader: expr, $field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {{
$field = $trait::read(&mut $reader $(, $read_arg)*)?;
}};
+ ($reader: expr, $field: ident, required_vec) => {{
+ let f: $crate::util::ser::WithoutLength<Vec<_>> = $crate::util::ser::Readable::read(&mut $reader)?;
+ $field = f.0;
+ }};
($reader: expr, $field: ident, vec_type) => {{
let f: $crate::util::ser::WithoutLength<Vec<_>> = $crate::util::ser::Readable::read(&mut $reader)?;
$field = Some(f.0);
($reader: expr, $field: ident, vec_type) => {{
let f: $crate::util::ser::WithoutLength<Vec<_>> = $crate::util::ser::Readable::read(&mut $reader)?;
$field = Some(f.0);
($field: ident, required) => {
$field.0.unwrap()
};
($field: ident, required) => {
$field.0.unwrap()
};
+ ($field: ident, required_vec) => {
+ $field
+ };
($field: ident, vec_type) => {
$field.unwrap()
};
($field: ident, vec_type) => {
$field.unwrap()
};
($field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {
$crate::_init_tlv_field_var!($field, required);
};
($field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {
$crate::_init_tlv_field_var!($field, required);
};
+ ($field: ident, required_vec) => {
+ let mut $field = Vec::new();
+ };
($field: ident, vec_type) => {
let mut $field = Some(Vec::new());
};
($field: ident, vec_type) => {
let mut $field = Some(Vec::new());
};