Skip to content

Commit 3b33b8c

Browse files
committed
Add optional support for compact_str crate
1 parent 32dacd3 commit 3b33b8c

4 files changed

Lines changed: 114 additions & 0 deletions

File tree

Cargo.lock

Lines changed: 48 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ exclude = ["fuzz/"]
1818
arrayvec = { version = "0.7", default-features = false, optional = true }
1919
bitcode_derive = { version = "=0.6.9", path = "./bitcode_derive", optional = true }
2020
bytemuck = { version = "1.14", features = [ "min_const_generics", "must_cast" ] }
21+
compact_str = { version = "0.9.0", optional = true }
2122
glam = { version = ">=0.21", default-features = false, optional = true }
2223
rust_decimal = { version = "1.36", default-features = false, optional = true }
2324
serde = { version = "1.0", default-features = false, features = [ "alloc" ], optional = true }

src/ext/compact_str.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use crate::coder::{Decoder, Encoder};
2+
use crate::derive::{Decode, Encode};
3+
use crate::str::{StrDecoder, StrEncoder};
4+
use compact_str::CompactString;
5+
6+
impl Encoder<CompactString> for StrEncoder {
7+
#[inline(always)]
8+
fn encode(&mut self, t: &CompactString) {
9+
self.encode(t.as_str())
10+
}
11+
}
12+
13+
impl Encode for CompactString {
14+
type Encoder = StrEncoder;
15+
}
16+
17+
// TODO: Can we optimize out copying from the reference? Just construct a CompactString from pointer/capacity/length if it exceeds the inline capacity?
18+
impl<'a> Decoder<'a, CompactString> for StrDecoder<'a> {
19+
#[inline(always)]
20+
fn decode(&mut self) -> CompactString {
21+
let s: &str = self.decode();
22+
s.into()
23+
}
24+
}
25+
26+
impl<'a> Decode<'a> for CompactString {
27+
type Decoder = StrDecoder<'a>;
28+
}
29+
30+
#[cfg(test)]
31+
mod tests {
32+
use crate::{decode, encode};
33+
use alloc::vec::Vec;
34+
use compact_str::CompactString;
35+
36+
#[test]
37+
fn compact_string() {
38+
let mut v = CompactString::default();
39+
v.push('0');
40+
v.push('1');
41+
let b = encode(&v);
42+
assert_eq!(decode::<CompactString>(&b).unwrap(), v);
43+
}
44+
45+
#[test]
46+
fn compact_string_long() {
47+
// CompactString inlines up to 23 bytes on 64-bit platforms; the English alphabet exceeds that at 26 bytes.
48+
let v = CompactString::new("abcdefghijklmnopqrstuvwxyz");
49+
let b = encode(&v);
50+
assert_eq!(decode::<CompactString>(&b).unwrap(), v);
51+
}
52+
53+
#[test]
54+
fn compact_string_vec() {
55+
let v = vec![
56+
CompactString::new("01"),
57+
CompactString::new("abcdefghijklmnopqrstuvwxyz"),
58+
];
59+
let b = encode(&v);
60+
let v2 = decode::<Vec<CompactString>>(&b).unwrap();
61+
assert_eq!(v, v2);
62+
}
63+
}

src/ext/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#[cfg(feature = "arrayvec")]
22
mod arrayvec;
3+
#[cfg(feature = "compact_str")]
4+
mod compact_str;
35
#[cfg(feature = "glam")]
46
#[rustfmt::skip] // Makes impl_struct! calls way longer.
57
mod glam;

0 commit comments

Comments
 (0)