Skip to content

Commit 077fc7f

Browse files
Moved compatibility to the /compatibility/ crate, made bincode-derive support #[bincode(crate = "bincode_2")]
1 parent 3cb6061 commit 077fc7f

File tree

10 files changed

+340
-127
lines changed

10 files changed

+340
-127
lines changed

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[workspace]
22
members = [
3-
"derive"
3+
"derive",
4+
"compatibility"
45
]
56

67
[package]
@@ -51,7 +52,6 @@ criterion = "0.3"
5152
rand = "0.8"
5253
uuid = { version = "0.8", features = ["serde"] }
5354
chrono = { version = "0.4", features = ["serde"] }
54-
bincode1 = { version = "1.0", package = "bincode" }
5555

5656
[[bench]]
5757
name = "varint"

compatibility/Cargo.toml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "bincode_compatibility"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
bincode_2 = { path = "..", package = "bincode" }
10+
bincode_1 = { version = "1", package = "bincode" }
11+
serde = { version = "1", features = ["derive"] }
12+
rand = "0.8"

compatibility/src/lib.rs

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#![cfg(test)]
2+
3+
use bincode_1::Options;
4+
5+
mod rand;
6+
mod sway;
7+
8+
pub fn test_same_with_config<T, C, O>(t: &T, bincode_1_options: O, bincode_2_config: C)
9+
where
10+
T: bincode_2::Encode + serde::Serialize + core::fmt::Debug,
11+
C: bincode_2::config::Config + Clone,
12+
O: bincode_1::Options + Clone,
13+
{
14+
let bincode_1_output = bincode_1_options.serialize(t).unwrap();
15+
let bincode_2_output = bincode_2::encode_to_vec(t, bincode_2_config).unwrap();
16+
17+
assert_eq!(
18+
bincode_1_output, bincode_2_output,
19+
"{:?} serializes differently",
20+
t
21+
);
22+
}
23+
24+
pub fn test_same<T>(t: T)
25+
where
26+
T: bincode_2::Encode + serde::Serialize + core::fmt::Debug,
27+
{
28+
test_same_with_config(
29+
&t,
30+
bincode_1::options()
31+
.with_big_endian()
32+
.with_varint_encoding(),
33+
bincode_2::config::legacy()
34+
.with_big_endian()
35+
.with_variable_int_encoding(),
36+
);
37+
test_same_with_config(
38+
&t,
39+
bincode_1::options()
40+
.with_little_endian()
41+
.with_varint_encoding(),
42+
bincode_2::config::legacy()
43+
.with_little_endian()
44+
.with_variable_int_encoding(),
45+
);
46+
test_same_with_config(
47+
&t,
48+
bincode_1::options()
49+
.with_big_endian()
50+
.with_fixint_encoding(),
51+
bincode_2::config::legacy()
52+
.with_big_endian()
53+
.with_fixed_int_encoding(),
54+
);
55+
test_same_with_config(
56+
&t,
57+
bincode_1::options()
58+
.with_little_endian()
59+
.with_fixint_encoding(),
60+
bincode_2::config::legacy()
61+
.with_little_endian()
62+
.with_fixed_int_encoding(),
63+
);
64+
}

compatibility/src/rand.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Simplified case, taken from:
2+
// https://github.com/rust-random/rand/blob/19404d68764ed08513131f82157e2ccad69dcf83/rand_pcg/src/pcg64.rs#L37-L40
3+
4+
use rand::Rng;
5+
6+
#[derive(Debug, bincode_2::Encode, bincode_2::Decode, serde::Serialize, serde::Deserialize)]
7+
#[bincode(crate = "bincode_2")]
8+
pub struct Lcg64Xsh32 {
9+
state: u64,
10+
increment: u64,
11+
}
12+
13+
#[test]
14+
pub fn test() {
15+
let mut rng = rand::thread_rng();
16+
for _ in 0..100 {
17+
crate::test_same(Lcg64Xsh32 {
18+
state: rng.gen(),
19+
increment: rng.gen(),
20+
});
21+
}
22+
}

compatibility/src/sway.rs

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Credits to Sway in the Rust Programming Language
2+
3+
use serde::{Deserialize, Serialize};
4+
5+
#[derive(bincode_2::Encode, bincode_2::Decode, serde::Serialize, serde::Deserialize, Debug)]
6+
#[bincode(crate = "bincode_2")]
7+
pub struct FTXresponseSuccess<T> {
8+
pub success: bool,
9+
pub result: T,
10+
}
11+
12+
#[derive(bincode_2::Encode, bincode_2::Decode, Serialize, Deserialize, Debug)]
13+
#[bincode(crate = "bincode_2")]
14+
pub struct FTXresponseFailure {
15+
pub success: bool,
16+
pub error: String,
17+
}
18+
19+
#[derive(bincode_2::Encode, bincode_2::Decode, Serialize, Deserialize, Debug)]
20+
#[bincode(crate = "bincode_2")]
21+
#[serde(untagged)]
22+
pub enum FTXresponse<T> {
23+
Result(FTXresponseSuccess<T>),
24+
Error(FTXresponseFailure),
25+
}
26+
27+
#[derive(bincode_2::Encode, bincode_2::Decode, Serialize, Deserialize, Debug)]
28+
#[bincode(crate = "bincode_2")]
29+
pub enum TradeSide {
30+
Buy,
31+
Sell,
32+
}
33+
34+
#[derive(bincode_2::Encode, bincode_2::Decode, Serialize, Deserialize, Debug)]
35+
#[bincode(crate = "bincode_2")]
36+
#[serde(rename_all = "camelCase")]
37+
pub struct Trade {
38+
pub id: u64,
39+
pub liquidation: bool,
40+
pub price: f64,
41+
pub side: TradeSide,
42+
pub size: f64,
43+
pub time: String,
44+
}

derive/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ description = "Implementation of #[derive(Encode, Decode)] for bincode"
1616
proc-macro = true
1717

1818
[dependencies]
19-
virtue = "0.0.4"
19+
virtue = "0.0.5"

derive/src/derive_enum.rs

+62-32
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
use super::FieldAttribute;
2+
use crate::CrateNameAttribute;
23
use virtue::generate::{FnSelfArg, Generator, StreamBuilder};
34
use virtue::parse::{EnumVariant, Fields};
45
use virtue::prelude::*;
56

67
const TUPLE_FIELD_PREFIX: &str = "field_";
78

8-
pub struct DeriveEnum {
9+
pub(crate) struct DeriveEnum {
910
pub variants: Vec<EnumVariant>,
11+
pub crate_name: CrateNameAttribute,
1012
}
1113

1214
impl DeriveEnum {
@@ -20,17 +22,22 @@ impl DeriveEnum {
2022

2123
pub fn generate_encode(self, generator: &mut Generator) -> Result<()> {
2224
generator
23-
.impl_for("bincode::Encode")?
25+
.impl_for(self.crate_name.ty("Encode"))?
2426
.modify_generic_constraints(|generics, where_constraints| {
2527
for g in generics.iter_generics() {
26-
where_constraints.push_constraint(g, "bincode::Encode").unwrap();
28+
where_constraints
29+
.push_constraint(g, self.crate_name.ty("Encode"))
30+
.unwrap();
2731
}
2832
})
2933
.generate_fn("encode")
30-
.with_generic("E", ["bincode::enc::Encoder"])
34+
.with_generic_deps("E", [self.crate_name.ty("enc::Encoder")])
3135
.with_self_arg(FnSelfArg::RefSelf)
3236
.with_arg("encoder", "&mut E")
33-
.with_return_type("core::result::Result<(), bincode::error::EncodeError>")
37+
.with_return_type(format!(
38+
"core::result::Result<(), {}::error::EncodeError>",
39+
self.crate_name.name
40+
))
3441
.body(|fn_body| {
3542
fn_body.ident_str("match");
3643
fn_body.ident_str("self");
@@ -76,7 +83,10 @@ impl DeriveEnum {
7683
// }
7784
match_body.group(Delimiter::Brace, |body| {
7885
// variant index
79-
body.push_parsed("<u32 as bincode::Encode>::encode")?;
86+
body.push_parsed(format!(
87+
"<u32 as {}::Encode>::encode",
88+
self.crate_name.name
89+
))?;
8090
body.group(Delimiter::Parenthesis, |args| {
8191
args.punct('&');
8292
args.group(Delimiter::Parenthesis, |num| {
@@ -91,17 +101,21 @@ impl DeriveEnum {
91101
body.punct(';');
92102
// If we have any fields, encode them all one by one
93103
for field_name in variant.fields.names() {
94-
if field_name.attributes().has_attribute(FieldAttribute::WithSerde)? {
104+
if field_name
105+
.attributes()
106+
.has_attribute(FieldAttribute::WithSerde)?
107+
{
95108
body.push_parsed(format!(
96-
"bincode::Encode::encode(&bincode::serde::Compat({}), encoder)?;",
109+
"{0}::Encode::encode(&{0}::serde::Compat({1}), encoder)?;",
110+
self.crate_name.name,
97111
field_name.to_string_with_prefix(TUPLE_FIELD_PREFIX),
98112
))?;
99113
} else {
100114
body.push_parsed(format!(
101-
"bincode::Encode::encode({}, encoder)?;",
115+
"{0}::Encode::encode({1}, encoder)?;",
116+
self.crate_name.name,
102117
field_name.to_string_with_prefix(TUPLE_FIELD_PREFIX),
103-
))
104-
?;
118+
))?;
105119
}
106120
}
107121
body.push_parsed("Ok(())")?;
@@ -142,7 +156,7 @@ impl DeriveEnum {
142156
result.puncts("=>");
143157
result.ident_str("Err");
144158
result.group(Delimiter::Parenthesis, |err_inner| {
145-
err_inner.push_parsed("bincode::error::DecodeError::UnexpectedVariant")?;
159+
err_inner.push_parsed(self.crate_name.ty("error::DecodeError::UnexpectedVariant"))?;
146160
err_inner.group(Delimiter::Brace, |variant_inner| {
147161
variant_inner.ident_str("found");
148162
variant_inner.punct(':');
@@ -159,7 +173,8 @@ impl DeriveEnum {
159173

160174
if self.variants.iter().any(|i| i.has_fixed_value()) {
161175
// we have fixed values, implement AllowedEnumVariants::Allowed
162-
variant_inner.push_parsed("bincode::error::AllowedEnumVariants::Allowed")?;
176+
variant_inner
177+
.push_parsed(self.crate_name.ty("error::AllowedEnumVariants::Allowed"))?;
163178
variant_inner.group(Delimiter::Parenthesis, |allowed_inner| {
164179
allowed_inner.punct('&');
165180
allowed_inner.group(Delimiter::Bracket, |allowed_slice| {
@@ -176,7 +191,8 @@ impl DeriveEnum {
176191
} else {
177192
// no fixed values, implement a range
178193
variant_inner.push_parsed(format!(
179-
"bincode::error::AllowedEnumVariants::Range {{ min: 0, max: {} }}",
194+
"{0}::error::AllowedEnumVariants::Range {{ min: 0, max: {1} }}",
195+
self.crate_name.name,
180196
self.variants.len() - 1
181197
))?;
182198
}
@@ -193,24 +209,28 @@ impl DeriveEnum {
193209
let enum_name = generator.target_name().to_string();
194210

195211
generator
196-
.impl_for("bincode::Decode")?
212+
.impl_for(self.crate_name.ty("Decode"))?
197213
.modify_generic_constraints(|generics, where_constraints| {
198214
for g in generics.iter_generics() {
199-
where_constraints.push_constraint(g, "bincode::Decode").unwrap();
215+
where_constraints.push_constraint(g, self.crate_name.ty("Decode")).unwrap();
200216
}
201217
})
202218
.generate_fn("decode")
203-
.with_generic("D", ["bincode::de::Decoder"])
219+
.with_generic_deps("D", [self.crate_name.ty("de::Decoder")])
204220
.with_arg("decoder", "&mut D")
205-
.with_return_type("core::result::Result<Self, bincode::error::DecodeError>")
221+
.with_return_type(format!("core::result::Result<Self, {}::error::DecodeError>", self.crate_name.name))
206222
.body(|fn_builder| {
207223
if self.variants.is_empty() {
208-
fn_builder.push_parsed("core::result::Result::Err(bincode::error::DecodeError::EmptyEnum { type_name: core::any::type_name::<Self>() })")?;
224+
fn_builder.push_parsed(format!(
225+
"core::result::Result::Err({}::error::DecodeError::EmptyEnum {{ type_name: core::any::type_name::<Self>() }})",
226+
self.crate_name.name
227+
))?;
209228
} else {
210229
fn_builder
211-
.push_parsed(
212-
"let variant_index = <u32 as bincode::Decode>::decode(decoder)?;",
213-
)?;
230+
.push_parsed(format!(
231+
"let variant_index = <u32 as {}::Decode>::decode(decoder)?;",
232+
self.crate_name.name
233+
))?;
214234
fn_builder.push_parsed("match variant_index")?;
215235
fn_builder.group(Delimiter::Brace, |variant_case| {
216236
for (mut variant_index, variant) in self.iter_fields() {
@@ -242,10 +262,16 @@ impl DeriveEnum {
242262
variant_body.punct(':');
243263
if field.attributes().has_attribute(FieldAttribute::WithSerde)? {
244264
variant_body
245-
.push_parsed("<bincode::serde::Compat<_> as bincode::Decode>::decode(decoder)?.0,")?;
265+
.push_parsed(format!(
266+
"<{0}::serde::Compat<_> as {0}::Decode>::decode(decoder)?.0,",
267+
self.crate_name.name
268+
))?;
246269
} else {
247270
variant_body
248-
.push_parsed("bincode::Decode::decode(decoder)?,")?;
271+
.push_parsed(format!(
272+
"{}::Decode::decode(decoder)?,",
273+
self.crate_name.name
274+
))?;
249275
}
250276
}
251277
Ok(())
@@ -266,25 +292,29 @@ impl DeriveEnum {
266292

267293
pub fn generate_borrow_decode(self, generator: &mut Generator) -> Result<()> {
268294
// Remember to keep this mostly in sync with generate_decode
295+
let crate_name = &self.crate_name;
269296

270297
let enum_name = generator.target_name().to_string();
271298

272-
generator.impl_for_with_lifetimes("bincode::BorrowDecode", &["__de"])?
299+
generator.impl_for_with_lifetimes(crate_name.ty("BorrowDecode"), ["__de"])?
273300
.modify_generic_constraints(|generics, where_constraints| {
274301
for g in generics.iter_generics() {
275-
where_constraints.push_constraint(g, "bincode::enc::BorrowDecode").unwrap();
302+
where_constraints.push_constraint(g, crate_name.ty("enc::BorrowDecode")).unwrap();
276303
}
277304
})
278305
.generate_fn("borrow_decode")
279-
.with_generic("D", ["bincode::de::BorrowDecoder<'__de>"])
306+
.with_generic_deps("D", [crate_name.ty("de::BorrowDecoder<'__de>")])
280307
.with_arg("decoder", "&mut D")
281-
.with_return_type("core::result::Result<Self, bincode::error::DecodeError>")
308+
.with_return_type(format!("core::result::Result<Self, {}::error::DecodeError>", crate_name.name))
282309
.body(|fn_builder| {
283310
if self.variants.is_empty() {
284-
fn_builder.push_parsed("core::result::Result::Err(bincode::error::DecodeError::EmptyEnum { type_name: core::any::type_name::<Self>() })")?;
311+
fn_builder.push_parsed(format!(
312+
"core::result::Result::Err({}::error::DecodeError::EmptyEnum {{ type_name: core::any::type_name::<Self>() }})",
313+
crate_name.name
314+
))?;
285315
} else {
286316
fn_builder
287-
.push_parsed("let variant_index = <u32 as bincode::Decode>::decode(decoder)?;")?;
317+
.push_parsed(format!("let variant_index = <u32 as {}::Decode>::decode(decoder)?;", crate_name.name))?;
288318
fn_builder.push_parsed("match variant_index")?;
289319
fn_builder.group(Delimiter::Brace, |variant_case| {
290320
for (mut variant_index, variant) in self.iter_fields() {
@@ -316,9 +346,9 @@ impl DeriveEnum {
316346
variant_body.punct(':');
317347
if field.attributes().has_attribute(FieldAttribute::WithSerde)? {
318348
variant_body
319-
.push_parsed("<bincode::serde::BorrowCompat<_> as bincode::BorrowDecode>::borrow_decode(decoder)?.0,")?;
349+
.push_parsed(format!("<{0}::serde::BorrowCompat<_> as {0}::BorrowDecode>::borrow_decode(decoder)?.0,", crate_name.name))?;
320350
} else {
321-
variant_body.push_parsed("bincode::BorrowDecode::borrow_decode(decoder)?,")?;
351+
variant_body.push_parsed(format!("{}::BorrowDecode::borrow_decode(decoder)?,", crate_name.name))?;
322352
}
323353
}
324354
Ok(())

0 commit comments

Comments
 (0)