Skip to content

Commit

Permalink
Made arrays with 32 elements or less never encode their length
Browse files Browse the repository at this point in the history
  • Loading branch information
Victor Koenders committed Mar 30, 2023
1 parent 3431e6e commit 7d66b2d
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 6 deletions.
12 changes: 8 additions & 4 deletions compatibility/src/lib.rs
Expand Up @@ -22,18 +22,22 @@ where
// This is what bincode 1 serializes to. This will be our comparison value.
let encoded = bincode_1_options.serialize(t).unwrap();

println!("Encoded {:?} as {:?}", t, encoded);
println!("Encoded {t:?} as {encoded:?}");

// Test bincode 2 encode
let bincode_2_output = bincode_2::encode_to_vec(t, bincode_2_config).unwrap();
assert_eq!(encoded, bincode_2_output, "{:?} serializes differently", t);
assert_eq!(
encoded,
bincode_2_output,
"{t:?} serializes differently\nbincode 2 config {:?}",
core::any::type_name::<C>(),
);

// Test bincode 2 serde serialize
let bincode_2_serde_output = bincode_2::serde::encode_to_vec(t, bincode_2_config).unwrap();
assert_eq!(
encoded, bincode_2_serde_output,
"{:?} serializes differently",
t
"{t:?} serializes differently"
);

// Test bincode 1 deserialize
Expand Down
1 change: 1 addition & 0 deletions compatibility/src/misc.rs
Expand Up @@ -2,6 +2,7 @@
fn test() {
super::test_same((1,));
super::test_same(TupleS(2.0, 3.0, 4.0));
super::test_same([2.0, 3.0, 4.0]);
super::test_same(Option::<u32>::Some(5));
super::test_same(Option::<u32>::None);
super::test_same(Result::<u32, u8>::Ok(5));
Expand Down
2 changes: 2 additions & 0 deletions src/config.rs
Expand Up @@ -253,6 +253,8 @@ impl InternalArrayLengthConfig for SkipFixedArrayLength {
}

/// Write the length of fixed size arrays (`[u8; N]`) before writing the array.
///
/// Because of how serde (and thus bincode 1) works, the length is never written when encoding an array with 32 elements or less. In those cases this flag does nothing.
#[derive(Copy, Clone)]
pub struct WriteFixedArrayLength {}

Expand Down
5 changes: 4 additions & 1 deletion src/de/impls.rs
Expand Up @@ -448,7 +448,10 @@ where
T: Decode + Sized + 'static,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
if !D::C::SKIP_FIXED_ARRAY_LENGTH {
// Serde implements arrays up to length 32, and those are implemented as a tuple (no length prefix)
// When an array is larger than 32, serde falls back to a slice implementation, which does write the length
// so we cannot write the slice length if the length is less than 32
if N > 32 && !D::C::SKIP_FIXED_ARRAY_LENGTH {
let length = super::decode_slice_len(decoder)?;
if length != N {
return Err(DecodeError::ArrayLengthMismatch {
Expand Down
5 changes: 4 additions & 1 deletion src/enc/impls.rs
Expand Up @@ -351,7 +351,10 @@ where
T: Encode,
{
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
if !E::C::SKIP_FIXED_ARRAY_LENGTH {
// Serde implements arrays up to length 32, and those are implemented as a tuple (no length prefix)
// When an array is larger than 32, serde falls back to a slice implementation, which does write the length
// so we cannot write the slice length if the length is less than 32
if N > 32 && !E::C::SKIP_FIXED_ARRAY_LENGTH {
super::encode_slice_len(encoder, N)?;
}
for item in self.iter() {
Expand Down

0 comments on commit 7d66b2d

Please sign in to comment.