Skip to content

Commit d3741d3

Browse files
Fix Encode derive for transparent structs (#52)
1 parent 7737481 commit d3741d3

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

ssz_derive/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ fn ssz_encode_derive_struct_transparent(
456456
let ssz_fields = parse_ssz_fields(struct_data);
457457
let num_fields = ssz_fields
458458
.iter()
459-
.filter(|(_, _, field_opts)| !field_opts.skip_deserializing)
459+
.filter(|(_, _, field_opts)| !field_opts.skip_serializing)
460460
.count();
461461

462462
if num_fields != 1 {
@@ -469,7 +469,7 @@ fn ssz_encode_derive_struct_transparent(
469469
let (index, (ty, ident, _field_opts)) = ssz_fields
470470
.iter()
471471
.enumerate()
472-
.find(|(_, (_, _, field_opts))| !field_opts.skip_deserializing)
472+
.find(|(_, (_, _, field_opts))| !field_opts.skip_serializing)
473473
.expect("\"transparent\" struct must have at least one non-skipped field");
474474

475475
// Remove the `_usize` suffix from the value to avoid a compiler warning.

ssz_derive/tests/tests.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,3 +257,45 @@ fn transparent_struct_newtype_skipped_field_reverse() {
257257
&vec![42_u8].as_ssz_bytes(),
258258
);
259259
}
260+
261+
#[derive(PartialEq, Debug, Encode)]
262+
#[ssz(struct_behaviour = "transparent")]
263+
struct TransparentStructSkippedFieldEncodeOnly {
264+
inner: Vec<u8>,
265+
#[ssz(skip_serializing)]
266+
skipped: PhantomData<u64>,
267+
}
268+
269+
// We implement Decode manually (without derive) so we can reuse `assert_encode_decode` in the test.
270+
impl Decode for TransparentStructSkippedFieldEncodeOnly {
271+
fn is_ssz_fixed_len() -> bool {
272+
<TransparentStructSkippedField as Decode>::is_ssz_fixed_len()
273+
}
274+
275+
fn ssz_fixed_len() -> usize {
276+
<TransparentStructSkippedField as Decode>::ssz_fixed_len()
277+
}
278+
279+
fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, ssz::DecodeError> {
280+
let value = TransparentStructSkippedField::from_ssz_bytes(bytes)?;
281+
Ok(Self {
282+
inner: value.inner,
283+
skipped: PhantomData,
284+
})
285+
}
286+
}
287+
288+
// This is a regression test for deriving *just* Encode on a struct with a single field.
289+
//
290+
// Previously this was buggy because the derive macro expected the skipped field to be marked as
291+
// `skip_deserializing` rather than `skip_serializing`.
292+
#[test]
293+
fn transparent_struct_newtype_skipped_encode_only() {
294+
assert_encode_decode(
295+
&TransparentStructSkippedFieldEncodeOnly {
296+
inner: vec![42_u8],
297+
skipped: PhantomData,
298+
},
299+
&vec![42_u8].as_ssz_bytes(),
300+
);
301+
}

0 commit comments

Comments
 (0)