Skip to content

Commit

Permalink
Add tinyvec support
Browse files Browse the repository at this point in the history
  • Loading branch information
Nemo157 committed May 14, 2023
1 parent 0eb566d commit aa6f7f9
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Update `sha2` to 0.10 (by @madninja)
* Tighten max-encoded length estimation to reduce overallocation of resizable buffers (by @mina86)
* Add optional support for encoding/decoding to `smallvec::SmallVec` (by @mina86)
* Add optional support for encoding/decoding to `tinyvec`'s various types

## 0.4.0 - 2020-11-06

Expand Down
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,22 @@ rustdoc-args = ["--cfg", "docsrs"]

[features]
default = ["std"]
std = ["alloc"]
alloc = []
std = ["alloc", "tinyvec?/std"]
alloc = ["tinyvec?/alloc"]
check = ["sha2"]
cb58 = ["sha2"]

[dependencies]
sha2 = { version = "0.10", optional = true, default-features = false }
smallvec = { version = "1", optional = true }
tinyvec = { version = "1.6.0", default-features = false, optional = true, features = ["grab_spare_slice"] }

[dev-dependencies]
criterion = "0.3"
base58 = "0.1.0"
rust-base58 = "0.0.4"
assert_matches = "1.3.0"
tinyvec = { version = "1.6.0", features = ["rustc_1_55"] }

[[bench]]
name = "encode"
Expand Down
45 changes: 45 additions & 0 deletions src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,51 @@ impl<A: smallvec::Array<Item = u8>> DecodeTarget for smallvec::SmallVec<A> {
}
}

#[cfg(feature = "tinyvec")]
impl<A: tinyvec::Array<Item = u8>> DecodeTarget for tinyvec::ArrayVec<A> {
fn decode_with(
&mut self,
max_len: usize,
f: impl for<'a> FnOnce(&'a mut [u8]) -> Result<usize>,
) -> Result<usize> {
let _ = max_len;
let original = self.len();
let len = f(self.grab_spare_slice_mut())?;
self.set_len(original + len);
Ok(len)
}
}

#[cfg(feature = "tinyvec")]
impl DecodeTarget for tinyvec::SliceVec<'_, u8> {
fn decode_with(
&mut self,
max_len: usize,
f: impl for<'a> FnOnce(&'a mut [u8]) -> Result<usize>,
) -> Result<usize> {
let _ = max_len;
let original = self.len();
let len = f(self.grab_spare_slice_mut())?;
self.set_len(original + len);
Ok(len)
}
}

#[cfg(all(feature = "tinyvec", feature = "alloc"))]
impl<A: tinyvec::Array<Item = u8>> DecodeTarget for tinyvec::TinyVec<A> {
fn decode_with(
&mut self,
max_len: usize,
f: impl for<'a> FnOnce(&'a mut [u8]) -> Result<usize>,
) -> Result<usize> {
let original = self.len();
self.resize(original + max_len, 0);
let len = f(&mut self[original..])?;
self.truncate(original + len);
Ok(len)
}
}

impl DecodeTarget for [u8] {
fn decode_with(
&mut self,
Expand Down
45 changes: 45 additions & 0 deletions src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,51 @@ impl<A: smallvec::Array<Item = u8>> EncodeTarget for smallvec::SmallVec<A> {
}
}

#[cfg(feature = "tinyvec")]
impl<A: tinyvec::Array<Item = u8>> EncodeTarget for tinyvec::ArrayVec<A> {
fn encode_with(
&mut self,
max_len: usize,
f: impl for<'a> FnOnce(&'a mut [u8]) -> Result<usize>,
) -> Result<usize> {
let _ = max_len;
let original = self.len();
let len = f(self.grab_spare_slice_mut())?;
self.set_len(original + len);
Ok(len)
}
}

#[cfg(feature = "tinyvec")]
impl EncodeTarget for tinyvec::SliceVec<'_, u8> {
fn encode_with(
&mut self,
max_len: usize,
f: impl for<'a> FnOnce(&'a mut [u8]) -> Result<usize>,
) -> Result<usize> {
let _ = max_len;
let original = self.len();
let len = f(self.grab_spare_slice_mut())?;
self.set_len(original + len);
Ok(len)
}
}

#[cfg(all(feature = "tinyvec", feature = "alloc"))]
impl<A: tinyvec::Array<Item = u8>> EncodeTarget for tinyvec::TinyVec<A> {
fn encode_with(
&mut self,
max_len: usize,
f: impl for<'a> FnOnce(&'a mut [u8]) -> Result<usize>,
) -> Result<usize> {
let original = self.len();
self.resize(original + max_len, 0);
let len = f(&mut self[original..])?;
self.truncate(original + len);
Ok(len)
}
}

#[cfg(feature = "alloc")]
impl EncodeTarget for String {
fn encode_with(
Expand Down
33 changes: 33 additions & 0 deletions tests/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,39 @@ fn test_decode() {
assert_eq!(Ok(val.len()), bs58::decode(s).into(&mut vec));
assert_eq!((PREFIX, val), vec.split_at(3));
}

#[cfg(feature = "tinyvec")]
{
{
let mut vec = tinyvec::ArrayVec::<[u8; 36]>::from_iter(PREFIX.iter().copied());
let res = bs58::decode(s).into(&mut vec);
if PREFIX.len() + val.len() <= vec.capacity() {
assert_eq!(Ok(val.len()), res);
assert_eq!((PREFIX, val), vec.split_at(3));
} else {
assert_eq!(Err(bs58::decode::Error::BufferTooSmall), res);
}
}

{
let mut array = [0; 36];
array[..PREFIX.len()].copy_from_slice(PREFIX);
let mut vec = tinyvec::SliceVec::from_slice_len(&mut array, PREFIX.len());
let res = bs58::decode(s).into(&mut vec);
if PREFIX.len() + val.len() <= vec.capacity() {
assert_eq!(Ok(val.len()), res);
assert_eq!((PREFIX, val), vec.split_at(3));
} else {
assert_eq!(Err(bs58::decode::Error::BufferTooSmall), res);
}
}

{
let mut vec = tinyvec::TinyVec::<[u8; 36]>::from(PREFIX);
assert_eq!(Ok(val.len()), bs58::decode(s).into(&mut vec));
assert_eq!((PREFIX, val), vec.split_at(3));
}
}
}
}

Expand Down
33 changes: 33 additions & 0 deletions tests/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,39 @@ fn test_encode() {
assert_eq!(Ok(s.len()), bs58::encode(val).into(&mut vec));
assert_eq!((PREFIX, s.as_bytes()), vec.split_at(3));
}

#[cfg(feature = "tinyvec")]
{
{
let mut vec = tinyvec::ArrayVec::<[u8; 36]>::from_iter(PREFIX.iter().copied());
let res = bs58::encode(val).into(&mut vec);
if PREFIX.len() + s.len() <= vec.capacity() {
assert_eq!(Ok(s.len()), res);
assert_eq!((PREFIX, s.as_bytes()), vec.split_at(3));
} else {
assert_eq!(Err(bs58::encode::Error::BufferTooSmall), res);
}
}

{
let mut array = [0; 36];
array[..PREFIX.len()].copy_from_slice(PREFIX);
let mut vec = tinyvec::SliceVec::from_slice_len(&mut array, PREFIX.len());
let res = bs58::encode(val).into(&mut vec);
if PREFIX.len() + s.len() <= vec.capacity() {
assert_eq!(Ok(s.len()), res);
assert_eq!((PREFIX, s.as_bytes()), vec.split_at(3));
} else {
assert_eq!(Err(bs58::encode::Error::BufferTooSmall), res);
}
}

{
let mut vec = tinyvec::TinyVec::<[u8; 36]>::from(PREFIX);
assert_eq!(Ok(s.len()), bs58::encode(val).into(&mut vec));
assert_eq!((PREFIX, s.as_bytes()), vec.split_at(3));
}
}
}
}

Expand Down

0 comments on commit aa6f7f9

Please sign in to comment.