-
-
Notifications
You must be signed in to change notification settings - Fork 277
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bincode 1 compatibility framework (#489)
* Added a basic compatibility test to compare bincode 1 and bincode 2 output * Moved compatibility to the /compatibility/ crate, made bincode-derive support `#[bincode(crate = "bincode_2")]` * Added decode/deserialize test to test_same * Added random test cases to compatibility/src/sway.rs * Added test for bincode_1::options().with_fixint_encoding() and bincode_2::config::legacy(). Added rand license * Added comments on why the configs are chosen
- Loading branch information
1 parent
4d12ecc
commit 9d70b8c
Showing
5 changed files
with
231 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
[workspace] | ||
members = [ | ||
"derive" | ||
"derive", | ||
"compatibility" | ||
] | ||
|
||
[package] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[package] | ||
name = "bincode_compatibility" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
bincode_2 = { path = "..", package = "bincode" } | ||
bincode_1 = { version = "1", package = "bincode" } | ||
serde = { version = "1", features = ["derive"] } | ||
rand = "0.8" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
#![cfg(test)] | ||
|
||
use ::rand::Rng; | ||
use bincode_1::Options; | ||
|
||
mod rand; | ||
mod sway; | ||
|
||
pub fn test_same_with_config<T, C, O>(t: &T, bincode_1_options: O, bincode_2_config: C) | ||
where | ||
T: bincode_2::Encode | ||
+ bincode_2::Decode | ||
+ serde::Serialize | ||
+ serde::de::DeserializeOwned | ||
+ core::fmt::Debug | ||
+ PartialEq, | ||
C: bincode_2::config::Config, | ||
O: bincode_1::Options + Copy, | ||
{ | ||
let bincode_1_output = bincode_1_options.serialize(t).unwrap(); | ||
let bincode_2_output = bincode_2::encode_to_vec(t, bincode_2_config).unwrap(); | ||
|
||
assert_eq!( | ||
bincode_1_output, bincode_2_output, | ||
"{:?} serializes differently", | ||
t | ||
); | ||
|
||
let decoded: T = bincode_1_options.deserialize(&bincode_1_output).unwrap(); | ||
assert_eq!(&decoded, t); | ||
let decoded: T = bincode_1_options.deserialize(&bincode_2_output).unwrap(); | ||
assert_eq!(&decoded, t); | ||
|
||
let decoded: T = bincode_2::decode_from_slice(&bincode_1_output, bincode_2_config) | ||
.unwrap() | ||
.0; | ||
assert_eq!(&decoded, t); | ||
let decoded: T = bincode_2::decode_from_slice(&bincode_2_output, bincode_2_config) | ||
.unwrap() | ||
.0; | ||
assert_eq!(&decoded, t); | ||
} | ||
|
||
pub fn test_same<T>(t: T) | ||
where | ||
T: bincode_2::Encode | ||
+ bincode_2::Decode | ||
+ serde::Serialize | ||
+ serde::de::DeserializeOwned | ||
+ core::fmt::Debug | ||
+ PartialEq, | ||
{ | ||
test_same_with_config( | ||
&t, | ||
// This is the config used internally by bincode 1 | ||
bincode_1::options().with_fixint_encoding(), | ||
// Should match `::legacy()` | ||
bincode_2::config::legacy(), | ||
); | ||
|
||
// Check a bunch of different configs: | ||
test_same_with_config( | ||
&t, | ||
bincode_1::options() | ||
.with_big_endian() | ||
.with_varint_encoding(), | ||
bincode_2::config::legacy() | ||
.with_big_endian() | ||
.with_variable_int_encoding(), | ||
); | ||
test_same_with_config( | ||
&t, | ||
bincode_1::options() | ||
.with_little_endian() | ||
.with_varint_encoding(), | ||
bincode_2::config::legacy() | ||
.with_little_endian() | ||
.with_variable_int_encoding(), | ||
); | ||
test_same_with_config( | ||
&t, | ||
bincode_1::options() | ||
.with_big_endian() | ||
.with_fixint_encoding(), | ||
bincode_2::config::legacy() | ||
.with_big_endian() | ||
.with_fixed_int_encoding(), | ||
); | ||
test_same_with_config( | ||
&t, | ||
bincode_1::options() | ||
.with_little_endian() | ||
.with_fixint_encoding(), | ||
bincode_2::config::legacy() | ||
.with_little_endian() | ||
.with_fixed_int_encoding(), | ||
); | ||
} | ||
|
||
pub fn gen_string(rng: &mut impl Rng) -> String { | ||
let len = rng.gen_range(0..100usize); | ||
let mut result = String::with_capacity(len * 4); | ||
for _ in 0..len { | ||
result.push(rng.gen_range('\0'..char::MAX)); | ||
} | ||
result | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// Simplified case, taken from: | ||
// https://github.com/rust-random/rand/blob/19404d68764ed08513131f82157e2ccad69dcf83/rand_pcg/src/pcg64.rs#L37-L40 | ||
// Original license: MIT OR Apache-2.0 | ||
|
||
use rand::Rng; | ||
|
||
#[derive( | ||
Debug, bincode_2::Encode, bincode_2::Decode, serde::Serialize, serde::Deserialize, PartialEq, | ||
)] | ||
#[bincode(crate = "bincode_2")] | ||
pub struct Lcg64Xsh32 { | ||
state: u64, | ||
increment: u64, | ||
} | ||
|
||
#[test] | ||
pub fn test() { | ||
let mut rng = rand::thread_rng(); | ||
for _ in 0..1000 { | ||
crate::test_same(Lcg64Xsh32 { | ||
state: rng.gen(), | ||
increment: rng.gen(), | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// Credits to Sway in the Rust Programming Language | ||
|
||
use rand::Rng; | ||
use serde::{Deserialize, Serialize}; | ||
|
||
#[test] | ||
pub fn test() { | ||
let mut rng = rand::thread_rng(); | ||
for _ in 0..1000 { | ||
crate::test_same(random(&mut rng)); | ||
} | ||
} | ||
|
||
fn random(rng: &mut impl Rng) -> FTXresponse<Trade> { | ||
if rng.gen() { | ||
FTXresponse::Result(FTXresponseSuccess { | ||
result: Trade::random(rng), | ||
success: rng.gen(), | ||
}) | ||
} else { | ||
FTXresponse::Error(FTXresponseFailure { | ||
success: rng.gen(), | ||
error: crate::gen_string(rng), | ||
}) | ||
} | ||
} | ||
|
||
#[derive(bincode_2::Encode, bincode_2::Decode, Serialize, Deserialize, Debug, PartialEq)] | ||
#[bincode(crate = "bincode_2")] | ||
pub enum FTXresponse<T> { | ||
Result(FTXresponseSuccess<T>), | ||
Error(FTXresponseFailure), | ||
} | ||
|
||
#[derive( | ||
bincode_2::Encode, bincode_2::Decode, serde::Serialize, serde::Deserialize, Debug, PartialEq, | ||
)] | ||
#[bincode(crate = "bincode_2")] | ||
pub struct FTXresponseSuccess<T> { | ||
pub success: bool, | ||
pub result: T, | ||
} | ||
|
||
#[derive(bincode_2::Encode, bincode_2::Decode, Serialize, Deserialize, Debug, PartialEq)] | ||
#[bincode(crate = "bincode_2")] | ||
pub struct FTXresponseFailure { | ||
pub success: bool, | ||
pub error: String, | ||
} | ||
|
||
#[derive(bincode_2::Encode, bincode_2::Decode, Serialize, Deserialize, Debug, PartialEq)] | ||
#[bincode(crate = "bincode_2")] | ||
pub enum TradeSide { | ||
Buy, | ||
Sell, | ||
} | ||
|
||
#[derive(bincode_2::Encode, bincode_2::Decode, Serialize, Deserialize, Debug, PartialEq)] | ||
#[bincode(crate = "bincode_2")] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct Trade { | ||
pub id: u64, | ||
pub liquidation: bool, | ||
pub price: f64, | ||
pub side: TradeSide, | ||
pub size: f64, | ||
pub time: String, | ||
} | ||
|
||
impl Trade { | ||
fn random(rng: &mut impl Rng) -> Self { | ||
Self { | ||
id: rng.gen(), | ||
liquidation: rng.gen(), | ||
price: rng.gen(), | ||
side: if rng.gen() { | ||
TradeSide::Buy | ||
} else { | ||
TradeSide::Sell | ||
}, | ||
size: rng.gen(), | ||
time: crate::gen_string(rng), | ||
} | ||
} | ||
} |