Skip to content

Commit 573dd3d

Browse files
authored
Merge pull request #14 from arpadav/main
Implement `bitcode`
2 parents 35eaea6 + 4e67f48 commit 573dd3d

4 files changed

Lines changed: 138 additions & 0 deletions

File tree

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ repository = "https://github.com/Synphonyte/codee"
1313

1414
[dependencies]
1515
base64 = { version = "0.22", optional = true }
16+
bitcode = { version = "0.6.6", optional = true }
1617
js-sys = { version = "0.3", optional = true }
1718
miniserde = { version = "0.1", optional = true }
1819
prost = { version = "0.14", optional = true }
@@ -38,6 +39,8 @@ json_serde = ["dep:serde_json", "dep:serde"]
3839
msgpack_serde = ["dep:rmp-serde", "dep:serde"]
3940
bincode = ["dep:bincode"]
4041
bincode_serde = ["dep:bincode_v1", "dep:serde"]
42+
bitcode = ["dep:bitcode"]
43+
bitcode_serde = ["dep:bitcode", "bitcode/serde", "dep:serde"]
4144
serde_lite = ["dep:serde-lite"]
4245
json_serde_wasm = [
4346
"dep:serde",

src/binary/bitcode.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/// A codec that relies on `bitcode` to encode data.
2+
///
3+
/// This is only available with the **`bitcode` feature** feature enabled.
4+
///
5+
/// If you want to use `serde` with bitcode, please use the `bitcode_serde` feature instead.
6+
pub struct BitcodeCodec;
7+
8+
impl<T: bitcode::Encode> crate::Encoder<T> for BitcodeCodec {
9+
type Error = ();
10+
type Encoded = Vec<u8>;
11+
12+
fn encode(val: &T) -> Result<Self::Encoded, Self::Error> {
13+
Ok(bitcode::encode(val))
14+
}
15+
}
16+
17+
impl<T: for<'a> bitcode::Decode<'a>> crate::Decoder<T> for BitcodeCodec {
18+
type Error = bitcode::Error;
19+
type Encoded = [u8];
20+
21+
fn decode(val: &Self::Encoded) -> Result<T, Self::Error> {
22+
bitcode::decode(val)
23+
}
24+
}
25+
26+
#[cfg(test)]
27+
mod tests {
28+
use crate::{Decoder, Encoder};
29+
30+
use super::*;
31+
32+
#[test]
33+
fn test_bitcode_codec() {
34+
#[derive(Clone, Debug, PartialEq, bitcode::Encode, bitcode::Decode)]
35+
struct Test {
36+
s: String,
37+
i: i32,
38+
}
39+
let t = Test {
40+
s: String::from("party time 🎉"),
41+
i: 42,
42+
};
43+
let enc = BitcodeCodec::encode(&t).unwrap();
44+
let dec: Test = BitcodeCodec::decode(&enc).unwrap();
45+
assert_eq!(dec, t);
46+
}
47+
48+
#[test]
49+
fn test_bitcode_codec_complex() {
50+
use std::collections::BTreeMap;
51+
use std::collections::HashMap;
52+
use std::sync::Arc;
53+
54+
#[derive(Debug, PartialEq, bitcode::Encode, bitcode::Decode)]
55+
struct Test {
56+
s: String,
57+
i: i32,
58+
m: HashMap<String, i32>,
59+
b: BTreeMap<String, i32>,
60+
a: Arc<String>,
61+
}
62+
let t = Test {
63+
s: String::from("party time 🎉"),
64+
i: 42,
65+
m: HashMap::from([("a".to_string(), 1), ("b".to_string(), 2)]),
66+
b: BTreeMap::from([("a".to_string(), 1), ("b".to_string(), 2)]),
67+
a: Arc::new(String::from("party time 🎉"))
68+
};
69+
let enc = BitcodeCodec::encode(&t).unwrap();
70+
let dec: Test = BitcodeCodec::decode(&enc).unwrap();
71+
assert_eq!(dec, t);
72+
}
73+
74+
#[test]
75+
fn test_bitcode_codec_error() {
76+
#[derive(bitcode::Encode, bitcode::Decode)]
77+
struct Test;
78+
let enc = [0];
79+
let dec: Result<Test, bitcode::Error> = BitcodeCodec::decode(&enc);
80+
assert!(dec.is_err());
81+
}
82+
}

src/binary/bitcode_serde.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
use crate::{Decoder, Encoder};
2+
3+
/// A codec that relies on `bitcode` and `serde` to encode data in the bitcode format.
4+
///
5+
/// This is only available with the **`bitcode_serde` feature** enabled.
6+
pub struct BitcodeSerdeCodec;
7+
8+
impl<T: serde::Serialize> Encoder<T> for BitcodeSerdeCodec {
9+
type Error = bitcode::Error;
10+
type Encoded = Vec<u8>;
11+
12+
fn encode(val: &T) -> Result<Self::Encoded, Self::Error> {
13+
bitcode::serialize(val)
14+
}
15+
}
16+
17+
impl<T: serde::de::DeserializeOwned> Decoder<T> for BitcodeSerdeCodec {
18+
type Error = bitcode::Error;
19+
type Encoded = [u8];
20+
21+
fn decode(val: &Self::Encoded) -> Result<T, Self::Error> {
22+
bitcode::deserialize(val)
23+
}
24+
}
25+
26+
#[cfg(test)]
27+
mod tests {
28+
use super::*;
29+
30+
#[test]
31+
fn test_bitcode_codec() {
32+
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
33+
struct Test {
34+
s: String,
35+
i: i32,
36+
}
37+
let t = Test {
38+
s: String::from("party time 🎉"),
39+
i: 42,
40+
};
41+
let enc = BitcodeSerdeCodec::encode(&t).unwrap();
42+
let dec: Test = BitcodeSerdeCodec::decode(&enc).unwrap();
43+
assert_eq!(dec, t);
44+
}
45+
}

src/binary/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
mod bincode;
33
#[cfg(feature = "bincode_serde")]
44
mod bincode_serde;
5+
#[cfg(feature = "bitcode")]
6+
mod bitcode;
7+
#[cfg(feature = "bitcode_serde")]
8+
mod bitcode_serde;
59
mod from_to_bytes;
610
#[cfg(feature = "msgpack_serde")]
711
mod msgpack_serde;
@@ -14,6 +18,10 @@ mod rkyv;
1418
pub use bincode::*;
1519
#[cfg(feature = "bincode_serde")]
1620
pub use bincode_serde::*;
21+
#[cfg(feature = "bitcode")]
22+
pub use bitcode::*;
23+
#[cfg(feature = "bitcode_serde")]
24+
pub use bitcode_serde::*;
1725
#[allow(unused_imports)]
1826
pub use from_to_bytes::*;
1927
#[cfg(feature = "msgpack_serde")]

0 commit comments

Comments
 (0)