Made arrays never encode their length (#625)
* Made arrays with 32 elements or less never encode their length * Removed `write_fixed_array_length` and `skip_fixed_array_length` as this was based on incorrect assumptions on how serde and bincode 1 works --------- Co-authored-by: Victor Koenders <victor.koenders@qrtech.se>
This commit is contained in:
parent
af4697e1fb
commit
dc468b4bed
|
|
@ -22,18 +22,22 @@ where
|
||||||
// This is what bincode 1 serializes to. This will be our comparison value.
|
// This is what bincode 1 serializes to. This will be our comparison value.
|
||||||
let encoded = bincode_1_options.serialize(t).unwrap();
|
let encoded = bincode_1_options.serialize(t).unwrap();
|
||||||
|
|
||||||
println!("Encoded {:?} as {:?}", t, encoded);
|
println!("Encoded {t:?} as {encoded:?}");
|
||||||
|
|
||||||
// Test bincode 2 encode
|
// Test bincode 2 encode
|
||||||
let bincode_2_output = bincode_2::encode_to_vec(t, bincode_2_config).unwrap();
|
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
|
// Test bincode 2 serde serialize
|
||||||
let bincode_2_serde_output = bincode_2::serde::encode_to_vec(t, bincode_2_config).unwrap();
|
let bincode_2_serde_output = bincode_2::serde::encode_to_vec(t, bincode_2_config).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
encoded, bincode_2_serde_output,
|
encoded, bincode_2_serde_output,
|
||||||
"{:?} serializes differently",
|
"{t:?} serializes differently"
|
||||||
t
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Test bincode 1 deserialize
|
// Test bincode 1 deserialize
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,83 @@ fn test() {
|
||||||
super::test_same(std::net::Ipv6Addr::LOCALHOST);
|
super::test_same(std::net::Ipv6Addr::LOCALHOST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_arrays() {
|
||||||
|
// serde is known to be weird with arrays
|
||||||
|
// Arrays of length 32 and less are encoded as tuples, but arrays 33 and up are encoded as slices
|
||||||
|
// we need to make sure we're compatible with this
|
||||||
|
super::test_same([0u8; 0]);
|
||||||
|
super::test_same([1u8; 1]);
|
||||||
|
super::test_same([1u8, 2]);
|
||||||
|
super::test_same([1u8, 2, 3]);
|
||||||
|
super::test_same([1u8, 2, 3, 4]);
|
||||||
|
super::test_same([1u8, 2, 3, 4, 5]);
|
||||||
|
super::test_same([1u8, 2, 3, 4, 5, 6]);
|
||||||
|
super::test_same([1u8, 2, 3, 4, 5, 6, 7]);
|
||||||
|
super::test_same([1u8, 2, 3, 4, 5, 6, 7, 8]);
|
||||||
|
super::test_same([1u8, 2, 3, 4, 5, 6, 7, 8, 9]);
|
||||||
|
super::test_same([1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||||
|
super::test_same([1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
|
||||||
|
super::test_same([1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
|
||||||
|
super::test_same([1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
|
||||||
|
super::test_same([1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]);
|
||||||
|
super::test_same([1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
|
||||||
|
super::test_same([1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
|
||||||
|
super::test_same([1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]);
|
||||||
|
super::test_same([
|
||||||
|
1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
|
||||||
|
]);
|
||||||
|
super::test_same([
|
||||||
|
1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||||
|
]);
|
||||||
|
super::test_same([
|
||||||
|
1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
|
||||||
|
]);
|
||||||
|
super::test_same([
|
||||||
|
1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
||||||
|
]);
|
||||||
|
super::test_same([
|
||||||
|
1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
|
||||||
|
]);
|
||||||
|
super::test_same([
|
||||||
|
1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
|
||||||
|
]);
|
||||||
|
super::test_same([
|
||||||
|
1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||||
|
]);
|
||||||
|
super::test_same([
|
||||||
|
1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
|
||||||
|
]);
|
||||||
|
super::test_same([
|
||||||
|
1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||||
|
25, 26,
|
||||||
|
]);
|
||||||
|
super::test_same([
|
||||||
|
1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||||
|
25, 26, 27,
|
||||||
|
]);
|
||||||
|
super::test_same([
|
||||||
|
1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||||
|
25, 26, 27, 28,
|
||||||
|
]);
|
||||||
|
super::test_same([
|
||||||
|
1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||||
|
25, 26, 27, 28, 29,
|
||||||
|
]);
|
||||||
|
super::test_same([
|
||||||
|
1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||||
|
25, 26, 27, 28, 29, 30,
|
||||||
|
]);
|
||||||
|
super::test_same([
|
||||||
|
1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||||
|
25, 26, 27, 28, 29, 30, 31,
|
||||||
|
]);
|
||||||
|
super::test_same([
|
||||||
|
1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||||
|
25, 26, 27, 28, 29, 30, 31, 32,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
bincode_2::Encode, bincode_2::Decode, serde::Serialize, serde::Deserialize, Debug, PartialEq,
|
bincode_2::Encode, bincode_2::Decode, serde::Serialize, serde::Deserialize, Debug, PartialEq,
|
||||||
)]
|
)]
|
||||||
|
|
|
||||||
16
docs/spec.md
16
docs/spec.md
|
|
@ -126,7 +126,7 @@ assert_eq!(encoded.as_slice(), &[
|
||||||
|
|
||||||
# Arrays
|
# Arrays
|
||||||
|
|
||||||
Array length is encoded based on the `.write_fixed_array_length` and `.skip_fixed_array_length()` config. When an array length is written, it will be encoded as a `u64`.
|
Array length is never encoded.
|
||||||
|
|
||||||
Note that `&[T]` is encoded as a [Collection](#collections).
|
Note that `&[T]` is encoded as a [Collection](#collections).
|
||||||
|
|
||||||
|
|
@ -135,15 +135,9 @@ Note that `&[T]` is encoded as a [Collection](#collections).
|
||||||
let arr: [u8; 5] = [10, 20, 30, 40, 50];
|
let arr: [u8; 5] = [10, 20, 30, 40, 50];
|
||||||
let encoded = bincode::encode_to_vec(arr, bincode::config::legacy()).unwrap();
|
let encoded = bincode::encode_to_vec(arr, bincode::config::legacy()).unwrap();
|
||||||
assert_eq!(encoded.as_slice(), &[
|
assert_eq!(encoded.as_slice(), &[
|
||||||
5, 0, 0, 0, 0, 0, 0, 0, // The length, as a u64
|
|
||||||
10, 20, 30, 40, 50, // the bytes
|
10, 20, 30, 40, 50, // the bytes
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let encoded = bincode::encode_to_vec(arr, bincode::config::legacy().skip_fixed_array_length()).unwrap();
|
|
||||||
assert_eq!(encoded.as_slice(), &[
|
|
||||||
// no length
|
|
||||||
10, 20, 30, 40, 50, // the bytes
|
|
||||||
]);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This applies to any type `T` that implements `Encode`/`Decode`
|
This applies to any type `T` that implements `Encode`/`Decode`
|
||||||
|
|
@ -168,14 +162,6 @@ let arr: [Foo; 2] = [
|
||||||
|
|
||||||
let encoded = bincode::encode_to_vec(&arr, bincode::config::legacy()).unwrap();
|
let encoded = bincode::encode_to_vec(&arr, bincode::config::legacy()).unwrap();
|
||||||
assert_eq!(encoded.as_slice(), &[
|
assert_eq!(encoded.as_slice(), &[
|
||||||
2, 0, 0, 0, 0, 0, 0, 0, // Length of the array
|
|
||||||
10, 20, // First Foo
|
|
||||||
30, 40, // Second Foo
|
|
||||||
]);
|
|
||||||
|
|
||||||
let encoded = bincode::encode_to_vec(&arr, bincode::config::legacy().skip_fixed_array_length()).unwrap();
|
|
||||||
assert_eq!(encoded.as_slice(), &[
|
|
||||||
// no length
|
|
||||||
10, 20, // First Foo
|
10, 20, // First Foo
|
||||||
30, 40, // Second Foo
|
30, 40, // Second Foo
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,7 @@
|
||||||
//! .with_little_endian()
|
//! .with_little_endian()
|
||||||
//! // pick one of:
|
//! // pick one of:
|
||||||
//! .with_variable_int_encoding()
|
//! .with_variable_int_encoding()
|
||||||
//! .with_fixed_int_encoding()
|
//! .with_fixed_int_encoding();
|
||||||
//! // pick one of:
|
|
||||||
//! .skip_fixed_array_length()
|
|
||||||
//! .write_fixed_array_length();
|
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! See [Configuration] for more information on the configuration options.
|
//! See [Configuration] for more information on the configuration options.
|
||||||
|
|
@ -29,20 +26,16 @@ use core::marker::PhantomData;
|
||||||
///
|
///
|
||||||
/// - [with_little_endian] and [with_big_endian]
|
/// - [with_little_endian] and [with_big_endian]
|
||||||
/// - [with_fixed_int_encoding] and [with_variable_int_encoding]
|
/// - [with_fixed_int_encoding] and [with_variable_int_encoding]
|
||||||
/// - [skip_fixed_array_length] and [write_fixed_array_length]
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// [with_little_endian]: #method.with_little_endian
|
/// [with_little_endian]: #method.with_little_endian
|
||||||
/// [with_big_endian]: #method.with_big_endian
|
/// [with_big_endian]: #method.with_big_endian
|
||||||
/// [with_fixed_int_encoding]: #method.with_fixed_int_encoding
|
/// [with_fixed_int_encoding]: #method.with_fixed_int_encoding
|
||||||
/// [with_variable_int_encoding]: #method.with_variable_int_encoding
|
/// [with_variable_int_encoding]: #method.with_variable_int_encoding
|
||||||
/// [skip_fixed_array_length]: #method.skip_fixed_array_length
|
|
||||||
/// [write_fixed_array_length]: #method.write_fixed_array_length
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct Configuration<E = LittleEndian, I = Varint, A = WriteFixedArrayLength, L = NoLimit> {
|
pub struct Configuration<E = LittleEndian, I = Varint, L = NoLimit> {
|
||||||
_e: PhantomData<E>,
|
_e: PhantomData<E>,
|
||||||
_i: PhantomData<I>,
|
_i: PhantomData<I>,
|
||||||
_a: PhantomData<A>,
|
|
||||||
_l: PhantomData<L>,
|
_l: PhantomData<L>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,7 +52,6 @@ pub struct Configuration<E = LittleEndian, I = Varint, A = WriteFixedArrayLength
|
||||||
/// The default config for bincode 2.0. By default this will be:
|
/// The default config for bincode 2.0. By default this will be:
|
||||||
/// - Little endian
|
/// - Little endian
|
||||||
/// - Variable int encoding
|
/// - Variable int encoding
|
||||||
/// - Write fixed array length
|
|
||||||
pub const fn standard() -> Configuration {
|
pub const fn standard() -> Configuration {
|
||||||
generate()
|
generate()
|
||||||
}
|
}
|
||||||
|
|
@ -67,34 +59,32 @@ pub const fn standard() -> Configuration {
|
||||||
/// Creates the "legacy" default config. This is the default config that was present in bincode 1.0
|
/// Creates the "legacy" default config. This is the default config that was present in bincode 1.0
|
||||||
/// - Little endian
|
/// - Little endian
|
||||||
/// - Fixed int length encoding
|
/// - Fixed int length encoding
|
||||||
/// - Write fixed array length
|
pub const fn legacy() -> Configuration<LittleEndian, Fixint, NoLimit> {
|
||||||
pub const fn legacy() -> Configuration<LittleEndian, Fixint, WriteFixedArrayLength, NoLimit> {
|
|
||||||
generate()
|
generate()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, I, A, L> Default for Configuration<E, I, A, L> {
|
impl<E, I, L> Default for Configuration<E, I, L> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
generate()
|
generate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn generate<E, I, A, L>() -> Configuration<E, I, A, L> {
|
const fn generate<E, I, L>() -> Configuration<E, I, L> {
|
||||||
Configuration {
|
Configuration {
|
||||||
_e: PhantomData,
|
_e: PhantomData,
|
||||||
_i: PhantomData,
|
_i: PhantomData,
|
||||||
_a: PhantomData,
|
|
||||||
_l: PhantomData,
|
_l: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, I, A, L> Configuration<E, I, A, L> {
|
impl<E, I, L> Configuration<E, I, L> {
|
||||||
/// Makes bincode encode all integer types in big endian.
|
/// Makes bincode encode all integer types in big endian.
|
||||||
pub const fn with_big_endian(self) -> Configuration<BigEndian, I, A, L> {
|
pub const fn with_big_endian(self) -> Configuration<BigEndian, I, L> {
|
||||||
generate()
|
generate()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes bincode encode all integer types in little endian.
|
/// Makes bincode encode all integer types in little endian.
|
||||||
pub const fn with_little_endian(self) -> Configuration<LittleEndian, I, A, L> {
|
pub const fn with_little_endian(self) -> Configuration<LittleEndian, I, L> {
|
||||||
generate()
|
generate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,7 +145,7 @@ impl<E, I, A, L> Configuration<E, I, A, L> {
|
||||||
///
|
///
|
||||||
/// Note that u256 and the like are unsupported by this format; if and when they are added to the
|
/// Note that u256 and the like are unsupported by this format; if and when they are added to the
|
||||||
/// language, they may be supported via the extension point given by the 255 byte.
|
/// language, they may be supported via the extension point given by the 255 byte.
|
||||||
pub const fn with_variable_int_encoding(self) -> Configuration<E, Varint, A, L> {
|
pub const fn with_variable_int_encoding(self) -> Configuration<E, Varint, L> {
|
||||||
generate()
|
generate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,51 +154,29 @@ impl<E, I, A, L> Configuration<E, I, A, L> {
|
||||||
/// * Fixed size integers are encoded directly
|
/// * Fixed size integers are encoded directly
|
||||||
/// * Enum discriminants are encoded as u32
|
/// * Enum discriminants are encoded as u32
|
||||||
/// * Lengths and usize are encoded as u64
|
/// * Lengths and usize are encoded as u64
|
||||||
pub const fn with_fixed_int_encoding(self) -> Configuration<E, Fixint, A, L> {
|
pub const fn with_fixed_int_encoding(self) -> Configuration<E, Fixint, L> {
|
||||||
generate()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Skip writing the length of fixed size arrays (`[u8; N]`) before writing the array
|
|
||||||
///
|
|
||||||
/// **NOTE:** This is not supported if you're using the `bincode::serde::*` functions, the `#[bincode(with_serde)]` attribute, or the `Compat` struct.
|
|
||||||
pub const fn skip_fixed_array_length(self) -> Configuration<E, I, SkipFixedArrayLength, L> {
|
|
||||||
generate()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Write the length of fixed size arrays (`[u8; N]`) before writing the array
|
|
||||||
pub const fn write_fixed_array_length(self) -> Configuration<E, I, WriteFixedArrayLength, L> {
|
|
||||||
generate()
|
generate()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the byte limit to `limit`.
|
/// Sets the byte limit to `limit`.
|
||||||
pub const fn with_limit<const N: usize>(self) -> Configuration<E, I, A, Limit<N>> {
|
pub const fn with_limit<const N: usize>(self) -> Configuration<E, I, Limit<N>> {
|
||||||
generate()
|
generate()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear the byte limit.
|
/// Clear the byte limit.
|
||||||
pub const fn with_no_limit(self) -> Configuration<E, I, A, NoLimit> {
|
pub const fn with_no_limit(self) -> Configuration<E, I, NoLimit> {
|
||||||
generate()
|
generate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Indicates a type is valid for controlling the bincode configuration
|
/// Indicates a type is valid for controlling the bincode configuration
|
||||||
pub trait Config:
|
pub trait Config:
|
||||||
InternalEndianConfig
|
InternalEndianConfig + InternalIntEncodingConfig + InternalLimitConfig + Copy + Clone
|
||||||
+ InternalArrayLengthConfig
|
|
||||||
+ InternalIntEncodingConfig
|
|
||||||
+ InternalLimitConfig
|
|
||||||
+ Copy
|
|
||||||
+ Clone
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Config for T where
|
impl<T> Config for T where
|
||||||
T: InternalEndianConfig
|
T: InternalEndianConfig + InternalIntEncodingConfig + InternalLimitConfig + Copy + Clone
|
||||||
+ InternalArrayLengthConfig
|
|
||||||
+ InternalIntEncodingConfig
|
|
||||||
+ InternalLimitConfig
|
|
||||||
+ Copy
|
|
||||||
+ Clone
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -244,22 +212,6 @@ impl InternalIntEncodingConfig for Varint {
|
||||||
const INT_ENCODING: IntEncoding = IntEncoding::Variable;
|
const INT_ENCODING: IntEncoding = IntEncoding::Variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Skip writing the length of fixed size arrays (`[u8; N]`) before writing the array.
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct SkipFixedArrayLength {}
|
|
||||||
|
|
||||||
impl InternalArrayLengthConfig for SkipFixedArrayLength {
|
|
||||||
const SKIP_FIXED_ARRAY_LENGTH: bool = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Write the length of fixed size arrays (`[u8; N]`) before writing the array.
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct WriteFixedArrayLength {}
|
|
||||||
|
|
||||||
impl InternalArrayLengthConfig for WriteFixedArrayLength {
|
|
||||||
const SKIP_FIXED_ARRAY_LENGTH: bool = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets an unlimited byte limit.
|
/// Sets an unlimited byte limit.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct NoLimit {}
|
pub struct NoLimit {}
|
||||||
|
|
@ -281,7 +233,7 @@ mod internal {
|
||||||
const ENDIAN: Endian;
|
const ENDIAN: Endian;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: InternalEndianConfig, I, A, L> InternalEndianConfig for Configuration<E, I, A, L> {
|
impl<E: InternalEndianConfig, I, L> InternalEndianConfig for Configuration<E, I, L> {
|
||||||
const ENDIAN: Endian = E::ENDIAN;
|
const ENDIAN: Endian = E::ENDIAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -295,9 +247,7 @@ mod internal {
|
||||||
const INT_ENCODING: IntEncoding;
|
const INT_ENCODING: IntEncoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, I: InternalIntEncodingConfig, A, L> InternalIntEncodingConfig
|
impl<E, I: InternalIntEncodingConfig, L> InternalIntEncodingConfig for Configuration<E, I, L> {
|
||||||
for Configuration<E, I, A, L>
|
|
||||||
{
|
|
||||||
const INT_ENCODING: IntEncoding = I::INT_ENCODING;
|
const INT_ENCODING: IntEncoding = I::INT_ENCODING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -307,21 +257,11 @@ mod internal {
|
||||||
Variable,
|
Variable,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait InternalArrayLengthConfig {
|
|
||||||
const SKIP_FIXED_ARRAY_LENGTH: bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E, I, A: InternalArrayLengthConfig, L> InternalArrayLengthConfig
|
|
||||||
for Configuration<E, I, A, L>
|
|
||||||
{
|
|
||||||
const SKIP_FIXED_ARRAY_LENGTH: bool = A::SKIP_FIXED_ARRAY_LENGTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait InternalLimitConfig {
|
pub trait InternalLimitConfig {
|
||||||
const LIMIT: Option<usize>;
|
const LIMIT: Option<usize>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, I, A, L: InternalLimitConfig> InternalLimitConfig for Configuration<E, I, A, L> {
|
impl<E, I, L: InternalLimitConfig> InternalLimitConfig for Configuration<E, I, L> {
|
||||||
const LIMIT: Option<usize> = L::LIMIT;
|
const LIMIT: Option<usize> = L::LIMIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,7 @@ use super::{
|
||||||
BorrowDecode, BorrowDecoder, Decode, Decoder,
|
BorrowDecode, BorrowDecoder, Decode, Decoder,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{
|
config::{Endian, IntEncoding, InternalEndianConfig, InternalIntEncodingConfig},
|
||||||
Endian, IntEncoding, InternalArrayLengthConfig, InternalEndianConfig,
|
|
||||||
InternalIntEncodingConfig,
|
|
||||||
},
|
|
||||||
error::{DecodeError, IntegerType},
|
error::{DecodeError, IntegerType},
|
||||||
impl_borrow_decode,
|
impl_borrow_decode,
|
||||||
};
|
};
|
||||||
|
|
@ -448,16 +445,6 @@ where
|
||||||
T: Decode + Sized + 'static,
|
T: Decode + Sized + 'static,
|
||||||
{
|
{
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
if !D::C::SKIP_FIXED_ARRAY_LENGTH {
|
|
||||||
let length = super::decode_slice_len(decoder)?;
|
|
||||||
if length != N {
|
|
||||||
return Err(DecodeError::ArrayLengthMismatch {
|
|
||||||
found: length,
|
|
||||||
required: N,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
decoder.claim_bytes_read(core::mem::size_of::<[T; N]>())?;
|
decoder.claim_bytes_read(core::mem::size_of::<[T; N]>())?;
|
||||||
|
|
||||||
// Optimize for `[u8; N]`
|
// Optimize for `[u8; N]`
|
||||||
|
|
@ -489,16 +476,6 @@ where
|
||||||
T: BorrowDecode<'de> + Sized + 'static,
|
T: BorrowDecode<'de> + Sized + 'static,
|
||||||
{
|
{
|
||||||
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
if !D::C::SKIP_FIXED_ARRAY_LENGTH {
|
|
||||||
let length = super::decode_slice_len(decoder)?;
|
|
||||||
if length != N {
|
|
||||||
return Err(DecodeError::ArrayLengthMismatch {
|
|
||||||
found: length,
|
|
||||||
required: N,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
decoder.claim_bytes_read(core::mem::size_of::<[T; N]>())?;
|
decoder.claim_bytes_read(core::mem::size_of::<[T; N]>())?;
|
||||||
|
|
||||||
// Optimize for `[u8; N]`
|
// Optimize for `[u8; N]`
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
use super::{write::Writer, Encode, Encoder};
|
use super::{write::Writer, Encode, Encoder};
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{
|
config::{Endian, IntEncoding, InternalEndianConfig, InternalIntEncodingConfig},
|
||||||
Endian, IntEncoding, InternalArrayLengthConfig, InternalEndianConfig,
|
|
||||||
InternalIntEncodingConfig,
|
|
||||||
},
|
|
||||||
error::EncodeError,
|
error::EncodeError,
|
||||||
};
|
};
|
||||||
use core::{
|
use core::{
|
||||||
|
|
@ -358,9 +355,6 @@ where
|
||||||
T: Encode,
|
T: Encode,
|
||||||
{
|
{
|
||||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
if !E::C::SKIP_FIXED_ARRAY_LENGTH {
|
|
||||||
super::encode_slice_len(encoder, N)?;
|
|
||||||
}
|
|
||||||
for item in self.iter() {
|
for item in self.iter() {
|
||||||
item.encode(encoder)?;
|
item.encode(encoder)?;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -444,6 +444,19 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cow_round_trip() {
|
||||||
|
let start = Cow::Borrowed("Foo");
|
||||||
|
let encoded = crate::encode_to_vec(&start, crate::config::standard()).unwrap();
|
||||||
|
let (end, _) =
|
||||||
|
crate::borrow_decode_from_slice::<Cow<str>, _>(&encoded, crate::config::standard())
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(start, end);
|
||||||
|
let (end, _) =
|
||||||
|
crate::decode_from_slice::<Cow<str>, _>(&encoded, crate::config::standard()).unwrap();
|
||||||
|
assert_eq!(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Decode for Rc<T>
|
impl<T> Decode for Rc<T>
|
||||||
where
|
where
|
||||||
T: Decode,
|
T: Decode,
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,6 @@ where
|
||||||
T: Deserialize<'de>,
|
T: Deserialize<'de>,
|
||||||
C: Config,
|
C: Config,
|
||||||
{
|
{
|
||||||
if C::SKIP_FIXED_ARRAY_LENGTH {
|
|
||||||
return Err(SerdeDecodeError::SkipFixedArrayLengthNotSupported.into());
|
|
||||||
}
|
|
||||||
let reader = crate::de::read::SliceReader::new(slice);
|
let reader = crate::de::read::SliceReader::new(slice);
|
||||||
let mut decoder = crate::de::DecoderImpl::new(reader, config);
|
let mut decoder = crate::de::DecoderImpl::new(reader, config);
|
||||||
let serde_decoder = SerdeDecoder {
|
let serde_decoder = SerdeDecoder {
|
||||||
|
|
@ -35,9 +32,6 @@ where
|
||||||
T: DeserializeSeed<'de>,
|
T: DeserializeSeed<'de>,
|
||||||
C: Config,
|
C: Config,
|
||||||
{
|
{
|
||||||
if C::SKIP_FIXED_ARRAY_LENGTH {
|
|
||||||
return Err(SerdeDecodeError::SkipFixedArrayLengthNotSupported.into());
|
|
||||||
}
|
|
||||||
let reader = crate::de::read::SliceReader::new(slice);
|
let reader = crate::de::read::SliceReader::new(slice);
|
||||||
let mut decoder = crate::de::DecoderImpl::new(reader, config);
|
let mut decoder = crate::de::DecoderImpl::new(reader, config);
|
||||||
let serde_decoder = SerdeDecoder {
|
let serde_decoder = SerdeDecoder {
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,6 @@ where
|
||||||
T: DeserializeOwned,
|
T: DeserializeOwned,
|
||||||
C: Config,
|
C: Config,
|
||||||
{
|
{
|
||||||
if C::SKIP_FIXED_ARRAY_LENGTH {
|
|
||||||
return Err(SerdeDecodeError::SkipFixedArrayLengthNotSupported.into());
|
|
||||||
}
|
|
||||||
let reader = crate::de::read::SliceReader::new(slice);
|
let reader = crate::de::read::SliceReader::new(slice);
|
||||||
let mut decoder = crate::de::DecoderImpl::new(reader, config);
|
let mut decoder = crate::de::DecoderImpl::new(reader, config);
|
||||||
let serde_decoder = SerdeDecoder { de: &mut decoder };
|
let serde_decoder = SerdeDecoder { de: &mut decoder };
|
||||||
|
|
@ -34,9 +31,6 @@ pub fn decode_from_std_read<D: DeserializeOwned, C: Config, R: std::io::Read>(
|
||||||
src: &mut R,
|
src: &mut R,
|
||||||
config: C,
|
config: C,
|
||||||
) -> Result<D, DecodeError> {
|
) -> Result<D, DecodeError> {
|
||||||
if C::SKIP_FIXED_ARRAY_LENGTH {
|
|
||||||
return Err(SerdeDecodeError::SkipFixedArrayLengthNotSupported.into());
|
|
||||||
}
|
|
||||||
let reader = crate::IoReader::new(src);
|
let reader = crate::IoReader::new(src);
|
||||||
let mut decoder = crate::de::DecoderImpl::new(reader, config);
|
let mut decoder = crate::de::DecoderImpl::new(reader, config);
|
||||||
let serde_decoder = SerdeDecoder { de: &mut decoder };
|
let serde_decoder = SerdeDecoder { de: &mut decoder };
|
||||||
|
|
@ -52,9 +46,6 @@ pub fn decode_from_reader<D: DeserializeOwned, R: Reader, C: Config>(
|
||||||
reader: R,
|
reader: R,
|
||||||
config: C,
|
config: C,
|
||||||
) -> Result<D, DecodeError> {
|
) -> Result<D, DecodeError> {
|
||||||
if C::SKIP_FIXED_ARRAY_LENGTH {
|
|
||||||
return Err(SerdeDecodeError::SkipFixedArrayLengthNotSupported.into());
|
|
||||||
}
|
|
||||||
let mut decoder = crate::de::DecoderImpl::<_, C>::new(reader, config);
|
let mut decoder = crate::de::DecoderImpl::<_, C>::new(reader, config);
|
||||||
let serde_decoder = SerdeDecoder { de: &mut decoder };
|
let serde_decoder = SerdeDecoder { de: &mut decoder };
|
||||||
D::deserialize(serde_decoder)
|
D::deserialize(serde_decoder)
|
||||||
|
|
|
||||||
|
|
@ -83,9 +83,6 @@ pub enum DecodeError {
|
||||||
/// Serde tried decoding a borrowed value from an owned reader. Use `serde_decode_borrowed_from_*` instead
|
/// Serde tried decoding a borrowed value from an owned reader. Use `serde_decode_borrowed_from_*` instead
|
||||||
CannotBorrowOwnedData,
|
CannotBorrowOwnedData,
|
||||||
|
|
||||||
/// Serde does not support skipping fixed array lengths
|
|
||||||
SkipFixedArrayLengthNotSupported,
|
|
||||||
|
|
||||||
/// Could not allocate data like `String` and `Vec<u8>`
|
/// Could not allocate data like `String` and `Vec<u8>`
|
||||||
#[cfg(not(feature = "alloc"))]
|
#[cfg(not(feature = "alloc"))]
|
||||||
CannotAllocate,
|
CannotAllocate,
|
||||||
|
|
@ -133,9 +130,6 @@ pub enum EncodeError {
|
||||||
/// Serde provided bincode with a sequence without a length, which is not supported in bincode
|
/// Serde provided bincode with a sequence without a length, which is not supported in bincode
|
||||||
SequenceMustHaveLength,
|
SequenceMustHaveLength,
|
||||||
|
|
||||||
/// Serde does not support skipping fixed array lengths
|
|
||||||
SkipFixedArrayLengthNotSupported,
|
|
||||||
|
|
||||||
/// [Serializer::collect_str] got called but bincode was unable to allocate memory.
|
/// [Serializer::collect_str] got called but bincode was unable to allocate memory.
|
||||||
#[cfg(not(feature = "alloc"))]
|
#[cfg(not(feature = "alloc"))]
|
||||||
CannotCollectStr,
|
CannotCollectStr,
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,6 @@ where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
C: Config,
|
C: Config,
|
||||||
{
|
{
|
||||||
if C::SKIP_FIXED_ARRAY_LENGTH {
|
|
||||||
return Err(SerdeEncodeError::SkipFixedArrayLengthNotSupported.into());
|
|
||||||
}
|
|
||||||
let mut encoder = crate::enc::EncoderImpl::new(crate::VecWriter::default(), config);
|
let mut encoder = crate::enc::EncoderImpl::new(crate::VecWriter::default(), config);
|
||||||
let serializer = SerdeEncoder { enc: &mut encoder };
|
let serializer = SerdeEncoder { enc: &mut encoder };
|
||||||
t.serialize(serializer)?;
|
t.serialize(serializer)?;
|
||||||
|
|
@ -31,9 +28,6 @@ where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
C: Config,
|
C: Config,
|
||||||
{
|
{
|
||||||
if C::SKIP_FIXED_ARRAY_LENGTH {
|
|
||||||
return Err(SerdeEncodeError::SkipFixedArrayLengthNotSupported.into());
|
|
||||||
}
|
|
||||||
let mut encoder =
|
let mut encoder =
|
||||||
crate::enc::EncoderImpl::new(crate::enc::write::SliceWriter::new(slice), config);
|
crate::enc::EncoderImpl::new(crate::enc::write::SliceWriter::new(slice), config);
|
||||||
let serializer = SerdeEncoder { enc: &mut encoder };
|
let serializer = SerdeEncoder { enc: &mut encoder };
|
||||||
|
|
@ -51,9 +45,6 @@ pub fn encode_into_writer<E: Serialize, W: Writer, C: Config>(
|
||||||
writer: W,
|
writer: W,
|
||||||
config: C,
|
config: C,
|
||||||
) -> Result<(), EncodeError> {
|
) -> Result<(), EncodeError> {
|
||||||
if C::SKIP_FIXED_ARRAY_LENGTH {
|
|
||||||
return Err(SerdeEncodeError::SkipFixedArrayLengthNotSupported.into());
|
|
||||||
}
|
|
||||||
let mut encoder = crate::enc::EncoderImpl::<_, C>::new(writer, config);
|
let mut encoder = crate::enc::EncoderImpl::<_, C>::new(writer, config);
|
||||||
let serializer = SerdeEncoder { enc: &mut encoder };
|
let serializer = SerdeEncoder { enc: &mut encoder };
|
||||||
val.serialize(serializer)?;
|
val.serialize(serializer)?;
|
||||||
|
|
@ -71,9 +62,6 @@ pub fn encode_into_std_write<E: Serialize, C: Config, W: std::io::Write>(
|
||||||
dst: &mut W,
|
dst: &mut W,
|
||||||
config: C,
|
config: C,
|
||||||
) -> Result<usize, EncodeError> {
|
) -> Result<usize, EncodeError> {
|
||||||
if C::SKIP_FIXED_ARRAY_LENGTH {
|
|
||||||
return Err(SerdeEncodeError::SkipFixedArrayLengthNotSupported.into());
|
|
||||||
}
|
|
||||||
let writer = crate::IoWriter::new(dst);
|
let writer = crate::IoWriter::new(dst);
|
||||||
let mut encoder = crate::enc::EncoderImpl::<_, C>::new(writer, config);
|
let mut encoder = crate::enc::EncoderImpl::<_, C>::new(writer, config);
|
||||||
let serializer = SerdeEncoder { enc: &mut encoder };
|
let serializer = SerdeEncoder { enc: &mut encoder };
|
||||||
|
|
|
||||||
|
|
@ -214,30 +214,25 @@ fn test_array() {
|
||||||
let mut buffer = [0u8; 32];
|
let mut buffer = [0u8; 32];
|
||||||
let input: [u8; 10] = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
|
let input: [u8; 10] = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
|
||||||
bincode::encode_into_slice(input, &mut buffer, bincode::config::standard()).unwrap();
|
bincode::encode_into_slice(input, &mut buffer, bincode::config::standard()).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(&buffer[..10], &[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]);
|
||||||
&buffer[..11],
|
|
||||||
&[10, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
|
|
||||||
);
|
|
||||||
|
|
||||||
let (output, len): ([u8; 10], usize) =
|
let (output, len): ([u8; 10], usize) =
|
||||||
bincode::decode_from_slice(&buffer[..11], bincode::config::standard()).unwrap();
|
bincode::decode_from_slice(&buffer[..11], bincode::config::standard()).unwrap();
|
||||||
assert_eq!(input, output);
|
assert_eq!(input, output);
|
||||||
assert_eq!(len, 11);
|
assert_eq!(len, 10);
|
||||||
|
|
||||||
let mut buffer = [0u8; 32];
|
let mut buffer = [0u8; 32];
|
||||||
let input: [u8; 1] = [1];
|
let input: [u8; 1] = [1];
|
||||||
let config = bincode::config::standard()
|
let config = bincode::config::standard()
|
||||||
.write_fixed_array_length()
|
|
||||||
.with_fixed_int_encoding()
|
.with_fixed_int_encoding()
|
||||||
.with_little_endian();
|
.with_little_endian();
|
||||||
let len = bincode::encode_into_slice(input, &mut buffer, config).unwrap();
|
let len = bincode::encode_into_slice(input, &mut buffer, config).unwrap();
|
||||||
assert_eq!(len, 9);
|
assert_eq!(len, 1);
|
||||||
assert_eq!(&buffer[..9], &[1, 0, 0, 0, 0, 0, 0, 0, 1]);
|
assert_eq!(&buffer[..1], &[1]);
|
||||||
|
|
||||||
let (output, len): (&[u8], usize) =
|
let (output, len): ([u8; 1], usize) = bincode::decode_from_slice(&buffer[..9], config).unwrap();
|
||||||
bincode::borrow_decode_from_slice(&buffer[..9], config).unwrap();
|
assert_eq!(len, 1);
|
||||||
assert_eq!(input, output);
|
assert_eq!(input, output);
|
||||||
assert_eq!(len, 9);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -422,7 +422,7 @@ mod zoxide {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
let dirs = &[
|
let dirs = vec![
|
||||||
Dir {
|
Dir {
|
||||||
path: Cow::Borrowed("Foo"),
|
path: Cow::Borrowed("Foo"),
|
||||||
rank: 1.23,
|
rank: 1.23,
|
||||||
|
|
|
||||||
|
|
@ -37,14 +37,11 @@ where
|
||||||
C: bincode::config::Config,
|
C: bincode::config::Config,
|
||||||
CMP: Fn(&V, &V) -> bool,
|
CMP: Fn(&V, &V) -> bool,
|
||||||
{
|
{
|
||||||
use bincode::error::EncodeError;
|
|
||||||
|
|
||||||
let mut buffer = [0u8; 2048];
|
let mut buffer = [0u8; 2048];
|
||||||
let len = bincode::serde::encode_into_slice(element, &mut buffer, config);
|
let len = bincode::serde::encode_into_slice(element, &mut buffer, config);
|
||||||
|
|
||||||
let decoded = bincode::serde::decode_from_slice(&buffer, config);
|
let decoded = bincode::serde::decode_from_slice(&buffer, config);
|
||||||
|
|
||||||
if !C::SKIP_FIXED_ARRAY_LENGTH {
|
|
||||||
let len = len.unwrap();
|
let len = len.unwrap();
|
||||||
let (decoded, decoded_len): (V, usize) = decoded.unwrap();
|
let (decoded, decoded_len): (V, usize) = decoded.unwrap();
|
||||||
println!(
|
println!(
|
||||||
|
|
@ -63,12 +60,6 @@ where
|
||||||
&buffer[..len],
|
&buffer[..len],
|
||||||
);
|
);
|
||||||
assert_eq!(len, decoded_len);
|
assert_eq!(len, decoded_len);
|
||||||
} else {
|
|
||||||
match len.unwrap_err() {
|
|
||||||
EncodeError::Serde(bincode::serde::EncodeError::SkipFixedArrayLengthNotSupported) => {}
|
|
||||||
err => panic!("Unexpected error: {:?}", err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn the_same_with_comparer<V, CMP>(element: V, cmp: CMP)
|
pub fn the_same_with_comparer<V, CMP>(element: V, cmp: CMP)
|
||||||
|
|
@ -81,32 +72,28 @@ where
|
||||||
&element,
|
&element,
|
||||||
bincode::config::standard()
|
bincode::config::standard()
|
||||||
.with_little_endian()
|
.with_little_endian()
|
||||||
.with_fixed_int_encoding()
|
.with_fixed_int_encoding(),
|
||||||
.skip_fixed_array_length(),
|
|
||||||
&cmp,
|
&cmp,
|
||||||
);
|
);
|
||||||
the_same_with_config(
|
the_same_with_config(
|
||||||
&element,
|
&element,
|
||||||
bincode::config::standard()
|
bincode::config::standard()
|
||||||
.with_big_endian()
|
.with_big_endian()
|
||||||
.with_fixed_int_encoding()
|
.with_fixed_int_encoding(),
|
||||||
.skip_fixed_array_length(),
|
|
||||||
&cmp,
|
&cmp,
|
||||||
);
|
);
|
||||||
the_same_with_config(
|
the_same_with_config(
|
||||||
&element,
|
&element,
|
||||||
bincode::config::standard()
|
bincode::config::standard()
|
||||||
.with_little_endian()
|
.with_little_endian()
|
||||||
.with_variable_int_encoding()
|
.with_variable_int_encoding(),
|
||||||
.skip_fixed_array_length(),
|
|
||||||
&cmp,
|
&cmp,
|
||||||
);
|
);
|
||||||
the_same_with_config(
|
the_same_with_config(
|
||||||
&element,
|
&element,
|
||||||
bincode::config::standard()
|
bincode::config::standard()
|
||||||
.with_big_endian()
|
.with_big_endian()
|
||||||
.with_variable_int_encoding()
|
.with_variable_int_encoding(),
|
||||||
.skip_fixed_array_length(),
|
|
||||||
&cmp,
|
&cmp,
|
||||||
);
|
);
|
||||||
the_same_with_config(
|
the_same_with_config(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue