Added unty dependency and added type checks (#667)
* Added unty dependency and added type checks * Bumped unty 0.0.2 * Bump unty to 0.0.3 * Removed unneeded + Sized requirements Optimize encode for [T; N] Made BinaryHeap<T> proxy to Vec<T> Made VecDeque decode/borrowdecode proxy to Vec<T> Optimize VecDeque::<u8>::Encode to write 2 slices directly Optimize Vec<u8> borrowdecode implementation --------- Co-authored-by: Victor Koenders <git@trang.ar>
This commit is contained in:
parent
feae25878a
commit
e03c9b06db
139
Cargo.toml
139
Cargo.toml
|
|
@ -1,69 +1,70 @@
|
|||
[workspace]
|
||||
members = ["derive", "compatibility"]
|
||||
|
||||
[package]
|
||||
name = "bincode"
|
||||
version = "2.0.0-rc.3" # remember to update html_root_url and bincode_derive
|
||||
authors = [
|
||||
"Ty Overby <ty@pre-alpha.com>",
|
||||
"Zoey Riordan <zoey@dos.cafe>",
|
||||
"Victor Koenders <bincode@trangar.com>",
|
||||
]
|
||||
exclude = ["logo.svg", "examples/*", ".gitignore", ".github/"]
|
||||
|
||||
publish = true
|
||||
|
||||
repository = "https://github.com/bincode-org/bincode"
|
||||
documentation = "https://docs.rs/bincode"
|
||||
readme = "./readme.md"
|
||||
categories = ["encoding", "network-programming"]
|
||||
keywords = ["binary", "encode", "decode", "serialize", "deserialize"]
|
||||
|
||||
license = "MIT"
|
||||
description = "A binary serialization / deserialization strategy for transforming structs into bytes and vice versa!"
|
||||
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
default = ["std", "derive"]
|
||||
std = ["alloc", "serde?/std"]
|
||||
alloc = ["serde?/alloc"]
|
||||
derive = ["bincode_derive"]
|
||||
|
||||
[dependencies]
|
||||
bincode_derive = { path = "derive", version = "2.0.0-rc.3", optional = true }
|
||||
serde = { version = "1.0", default-features = false, optional = true }
|
||||
|
||||
# Used for tests
|
||||
[dev-dependencies]
|
||||
serde_derive = "1.0"
|
||||
serde_json = { version = "1.0", default-features = false }
|
||||
tempfile = "3.2"
|
||||
criterion = "0.5"
|
||||
rand = "0.8"
|
||||
uuid = { version = "1.1", features = ["serde"] }
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
glam = { version = "0.24", features = ["serde"] }
|
||||
bincode_1 = { version = "1.3", package = "bincode" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
[[bench]]
|
||||
name = "varint"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "inline"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "string"
|
||||
harness = false
|
||||
|
||||
[profile.bench]
|
||||
codegen-units = 1
|
||||
debug = 1
|
||||
lto = true
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
[workspace]
|
||||
members = ["derive", "compatibility"]
|
||||
|
||||
[package]
|
||||
name = "bincode"
|
||||
version = "2.0.0-rc.3" # remember to update html_root_url and bincode_derive
|
||||
authors = [
|
||||
"Ty Overby <ty@pre-alpha.com>",
|
||||
"Zoey Riordan <zoey@dos.cafe>",
|
||||
"Victor Koenders <bincode@trangar.com>",
|
||||
]
|
||||
exclude = ["logo.svg", "examples/*", ".gitignore", ".github/"]
|
||||
|
||||
publish = true
|
||||
|
||||
repository = "https://github.com/bincode-org/bincode"
|
||||
documentation = "https://docs.rs/bincode"
|
||||
readme = "./readme.md"
|
||||
categories = ["encoding", "network-programming"]
|
||||
keywords = ["binary", "encode", "decode", "serialize", "deserialize"]
|
||||
|
||||
license = "MIT"
|
||||
description = "A binary serialization / deserialization strategy for transforming structs into bytes and vice versa!"
|
||||
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
default = ["std", "derive"]
|
||||
std = ["alloc", "serde?/std"]
|
||||
alloc = ["serde?/alloc"]
|
||||
derive = ["bincode_derive"]
|
||||
|
||||
[dependencies]
|
||||
bincode_derive = { path = "derive", version = "2.0.0-rc.3", optional = true }
|
||||
serde = { version = "1.0", default-features = false, optional = true }
|
||||
unty = "0.0.3"
|
||||
|
||||
# Used for tests
|
||||
[dev-dependencies]
|
||||
serde_derive = "1.0"
|
||||
serde_json = { version = "1.0", default-features = false }
|
||||
tempfile = "3.2"
|
||||
criterion = "0.5"
|
||||
rand = "0.8"
|
||||
uuid = { version = "1.1", features = ["serde"] }
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
glam = { version = "0.24", features = ["serde"] }
|
||||
bincode_1 = { version = "1.3", package = "bincode" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
[[bench]]
|
||||
name = "varint"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "inline"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "string"
|
||||
harness = false
|
||||
|
||||
[profile.bench]
|
||||
codegen-units = 1
|
||||
debug = 1
|
||||
lto = true
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
|
|
|||
|
|
@ -441,65 +441,61 @@ impl<'a, 'de: 'a> BorrowDecode<'de> for &'a str {
|
|||
|
||||
impl<T, const N: usize> Decode for [T; N]
|
||||
where
|
||||
T: Decode + Sized,
|
||||
T: Decode,
|
||||
{
|
||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||
decoder.claim_bytes_read(core::mem::size_of::<[T; N]>())?;
|
||||
|
||||
// TODO: we can't limit `T: 'static` because that would break other things
|
||||
// but we want to have this optimization
|
||||
// This will be another contendor for specialization implementation
|
||||
// if TypeId::of::<u8>() == TypeId::of::<T>() {
|
||||
// let mut buf = [0u8; N];
|
||||
// decoder.reader().read(&mut buf)?;
|
||||
// let ptr = &mut buf as *mut _ as *mut [T; N];
|
||||
if unty::type_equal::<T, u8>() {
|
||||
let mut buf = [0u8; N];
|
||||
decoder.reader().read(&mut buf)?;
|
||||
let ptr = &mut buf as *mut _ as *mut [T; N];
|
||||
|
||||
// // Safety: we know that T is a u8, so it is perfectly safe to
|
||||
// // translate an array of u8 into an array of T
|
||||
// let res = unsafe { ptr.read() };
|
||||
// Ok(res)
|
||||
// }
|
||||
let result = super::impl_core::collect_into_array(&mut (0..N).map(|_| {
|
||||
// See the documentation on `unclaim_bytes_read` as to why we're doing this here
|
||||
decoder.unclaim_bytes_read(core::mem::size_of::<T>());
|
||||
T::decode(decoder)
|
||||
}));
|
||||
// Safety: we know that T is a u8, so it is perfectly safe to
|
||||
// translate an array of u8 into an array of T
|
||||
let res = unsafe { ptr.read() };
|
||||
Ok(res)
|
||||
} else {
|
||||
let result = super::impl_core::collect_into_array(&mut (0..N).map(|_| {
|
||||
// See the documentation on `unclaim_bytes_read` as to why we're doing this here
|
||||
decoder.unclaim_bytes_read(core::mem::size_of::<T>());
|
||||
T::decode(decoder)
|
||||
}));
|
||||
|
||||
// result is only None if N does not match the values of `(0..N)`, which it always should
|
||||
// So this unwrap should never occur
|
||||
result.unwrap()
|
||||
// result is only None if N does not match the values of `(0..N)`, which it always should
|
||||
// So this unwrap should never occur
|
||||
result.unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, T, const N: usize> BorrowDecode<'de> for [T; N]
|
||||
where
|
||||
T: BorrowDecode<'de> + Sized,
|
||||
T: BorrowDecode<'de>,
|
||||
{
|
||||
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||
decoder.claim_bytes_read(core::mem::size_of::<[T; N]>())?;
|
||||
|
||||
// TODO: we can't limit `T: 'static` because that would break other things
|
||||
// but we want to have this optimization
|
||||
// This will be another contendor for specialization implementation
|
||||
// if TypeId::of::<u8>() == TypeId::of::<T>() {
|
||||
// let mut buf = [0u8; N];
|
||||
// decoder.reader().read(&mut buf)?;
|
||||
// let ptr = &mut buf as *mut _ as *mut [T; N];
|
||||
if unty::type_equal::<T, u8>() {
|
||||
let mut buf = [0u8; N];
|
||||
decoder.reader().read(&mut buf)?;
|
||||
let ptr = &mut buf as *mut _ as *mut [T; N];
|
||||
|
||||
// // Safety: we know that T is a u8, so it is perfectly safe to
|
||||
// // translate an array of u8 into an array of T
|
||||
// let res = unsafe { ptr.read() };
|
||||
// Ok(res)
|
||||
// }
|
||||
let result = super::impl_core::collect_into_array(&mut (0..N).map(|_| {
|
||||
// See the documentation on `unclaim_bytes_read` as to why we're doing this here
|
||||
decoder.unclaim_bytes_read(core::mem::size_of::<T>());
|
||||
T::borrow_decode(decoder)
|
||||
}));
|
||||
// Safety: we know that T is a u8, so it is perfectly safe to
|
||||
// translate an array of u8 into an array of T
|
||||
let res = unsafe { ptr.read() };
|
||||
Ok(res)
|
||||
} else {
|
||||
let result = super::impl_core::collect_into_array(&mut (0..N).map(|_| {
|
||||
// See the documentation on `unclaim_bytes_read` as to why we're doing this here
|
||||
decoder.unclaim_bytes_read(core::mem::size_of::<T>());
|
||||
T::borrow_decode(decoder)
|
||||
}));
|
||||
|
||||
// result is only None if N does not match the values of `(0..N)`, which it always should
|
||||
// So this unwrap should never occur
|
||||
result.unwrap()
|
||||
// result is only None if N does not match the values of `(0..N)`, which it always should
|
||||
// So this unwrap should never occur
|
||||
result.unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -547,22 +543,6 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
// BlockedTODO: https://github.com/rust-lang/rust/issues/37653
|
||||
//
|
||||
// We'll want to implement BorrowDecode for both Option<&[u8]> and Option<&[T: Encode]>,
|
||||
// but those implementations overlap because &'a [u8] also implements BorrowDecode
|
||||
// impl<'a, 'de: 'a> BorrowDecode<'de> for Option<&'a [u8]> {
|
||||
// fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||
// match super::decode_option_variant(decoder, core::any::type_name::<Option<&[u8]>>())? {
|
||||
// Some(_) => {
|
||||
// let val = BorrowDecode::borrow_decode(decoder)?;
|
||||
// Ok(Some(val))
|
||||
// }
|
||||
// None => Ok(None),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
impl<T, U> Decode for Result<T, U>
|
||||
where
|
||||
T: Decode,
|
||||
|
|
|
|||
|
|
@ -280,24 +280,15 @@ impl Encode for char {
|
|||
}
|
||||
}
|
||||
|
||||
// BlockedTODO: https://github.com/rust-lang/rust/issues/37653
|
||||
//
|
||||
// We'll want to implement encoding for both &[u8] and &[T: Encode],
|
||||
// but those implementations overlap because u8 also implements Encode
|
||||
// impl Encode for &'_ [u8] {
|
||||
// fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||
// encoder.writer().write(*self)
|
||||
// }
|
||||
// }
|
||||
|
||||
impl<T> Encode for [T]
|
||||
where
|
||||
T: Encode + 'static,
|
||||
T: Encode,
|
||||
{
|
||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||
super::encode_slice_len(encoder, self.len())?;
|
||||
|
||||
if core::any::TypeId::of::<T>() == core::any::TypeId::of::<u8>() {
|
||||
if unty::type_equal::<T, u8>() {
|
||||
// Safety: T = u8
|
||||
let t: &[u8] = unsafe { core::mem::transmute(self) };
|
||||
encoder.writer().write(t)?;
|
||||
return Ok(());
|
||||
|
|
@ -355,10 +346,17 @@ where
|
|||
T: Encode,
|
||||
{
|
||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||
for item in self.iter() {
|
||||
item.encode(encoder)?;
|
||||
if unty::type_equal::<T, u8>() {
|
||||
// Safety: this is &[u8; N]
|
||||
let array_slice: &[u8] =
|
||||
unsafe { core::slice::from_raw_parts(self.as_ptr().cast(), N) };
|
||||
encoder.writer().write(array_slice)
|
||||
} else {
|
||||
for item in self.iter() {
|
||||
item.encode(encoder)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{
|
||||
de::{BorrowDecoder, Decode, Decoder},
|
||||
de::{read::Reader, BorrowDecoder, Decode, Decoder},
|
||||
enc::{
|
||||
self,
|
||||
write::{SizeWriter, Writer},
|
||||
|
|
@ -8,8 +8,6 @@ use crate::{
|
|||
error::{DecodeError, EncodeError},
|
||||
impl_borrow_decode, BorrowDecode, Config,
|
||||
};
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
use alloc::sync::Arc;
|
||||
use alloc::{
|
||||
borrow::{Cow, ToOwned},
|
||||
boxed::Box,
|
||||
|
|
@ -19,6 +17,9 @@ use alloc::{
|
|||
vec::Vec,
|
||||
};
|
||||
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
use alloc::sync::Arc;
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct VecWriter {
|
||||
inner: Vec<u8>,
|
||||
|
|
@ -67,18 +68,7 @@ where
|
|||
T: Decode + Ord,
|
||||
{
|
||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||
let len = crate::de::decode_slice_len(decoder)?;
|
||||
decoder.claim_container_read::<T>(len)?;
|
||||
|
||||
let mut map = BinaryHeap::with_capacity(len);
|
||||
for _ in 0..len {
|
||||
// See the documentation on `unclaim_bytes_read` as to why we're doing this here
|
||||
decoder.unclaim_bytes_read(core::mem::size_of::<T>());
|
||||
|
||||
let key = T::decode(decoder)?;
|
||||
map.push(key);
|
||||
}
|
||||
Ok(map)
|
||||
Ok(Vec::<T>::decode(decoder)?.into())
|
||||
}
|
||||
}
|
||||
impl<'de, T> BorrowDecode<'de> for BinaryHeap<T>
|
||||
|
|
@ -86,18 +76,7 @@ where
|
|||
T: BorrowDecode<'de> + Ord,
|
||||
{
|
||||
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||
let len = crate::de::decode_slice_len(decoder)?;
|
||||
decoder.claim_container_read::<T>(len)?;
|
||||
|
||||
let mut map = BinaryHeap::with_capacity(len);
|
||||
for _ in 0..len {
|
||||
// See the documentation on `unclaim_bytes_read` as to why we're doing this here
|
||||
decoder.unclaim_bytes_read(core::mem::size_of::<T>());
|
||||
|
||||
let key = T::borrow_decode(decoder)?;
|
||||
map.push(key);
|
||||
}
|
||||
Ok(map)
|
||||
Ok(Vec::<T>::borrow_decode(decoder)?.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -106,6 +85,7 @@ where
|
|||
T: Encode + Ord,
|
||||
{
|
||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||
// BLOCKEDTODO(https://github.com/rust-lang/rust/issues/83659): we can u8 optimize this with `.as_slice()`
|
||||
crate::enc::encode_slice_len(encoder, self.len())?;
|
||||
for val in self.iter() {
|
||||
val.encode(encoder)?;
|
||||
|
|
@ -229,18 +209,7 @@ where
|
|||
T: Decode,
|
||||
{
|
||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||
let len = crate::de::decode_slice_len(decoder)?;
|
||||
decoder.claim_container_read::<T>(len)?;
|
||||
|
||||
let mut map = VecDeque::with_capacity(len);
|
||||
for _ in 0..len {
|
||||
// See the documentation on `unclaim_bytes_read` as to why we're doing this here
|
||||
decoder.unclaim_bytes_read(core::mem::size_of::<T>());
|
||||
|
||||
let key = T::decode(decoder)?;
|
||||
map.push_back(key);
|
||||
}
|
||||
Ok(map)
|
||||
Ok(Vec::<T>::decode(decoder)?.into())
|
||||
}
|
||||
}
|
||||
impl<'de, T> BorrowDecode<'de> for VecDeque<T>
|
||||
|
|
@ -248,18 +217,7 @@ where
|
|||
T: BorrowDecode<'de>,
|
||||
{
|
||||
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||
let len = crate::de::decode_slice_len(decoder)?;
|
||||
decoder.claim_container_read::<T>(len)?;
|
||||
|
||||
let mut map = VecDeque::with_capacity(len);
|
||||
for _ in 0..len {
|
||||
// See the documentation on `unclaim_bytes_read` as to why we're doing this here
|
||||
decoder.unclaim_bytes_read(core::mem::size_of::<T>());
|
||||
|
||||
let key = T::borrow_decode(decoder)?;
|
||||
map.push_back(key);
|
||||
}
|
||||
Ok(map)
|
||||
Ok(Vec::<T>::borrow_decode(decoder)?.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -269,8 +227,22 @@ where
|
|||
{
|
||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||
crate::enc::encode_slice_len(encoder, self.len())?;
|
||||
for item in self.iter() {
|
||||
item.encode(encoder)?;
|
||||
if unty::type_equal::<T, u8>() {
|
||||
let slices: (&[T], &[T]) = self.as_slices();
|
||||
// Safety: T is u8 so turning this into `&[u8]` is okay
|
||||
let slices: (&[u8], &[u8]) = unsafe {
|
||||
(
|
||||
core::slice::from_raw_parts(slices.0.as_ptr().cast(), slices.0.len()),
|
||||
core::slice::from_raw_parts(slices.1.as_ptr().cast(), slices.1.len()),
|
||||
)
|
||||
};
|
||||
|
||||
encoder.writer().write(slices.0)?;
|
||||
encoder.writer().write(slices.1)?;
|
||||
} else {
|
||||
for item in self.iter() {
|
||||
item.encode(encoder)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -283,28 +255,26 @@ where
|
|||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||
let len = crate::de::decode_slice_len(decoder)?;
|
||||
|
||||
// TODO: we can't limit `T: 'static` because that would break other things
|
||||
// but we want to have this optimization
|
||||
// This will be another contendor for specialization implementation
|
||||
// if core::any::TypeId::of::<T>() == core::any::TypeId::of::<u8>() {
|
||||
// decoder.claim_container_read::<T>(len)?;
|
||||
// // optimize for reading u8 vecs
|
||||
// let mut vec = Vec::new();
|
||||
// vec.resize(len, 0u8);
|
||||
// decoder.reader().read(&mut vec)?;
|
||||
// // Safety: Vec<T> is Vec<u8>
|
||||
// return Ok(unsafe { core::mem::transmute(vec) });
|
||||
// }
|
||||
decoder.claim_container_read::<T>(len)?;
|
||||
if unty::type_equal::<T, u8>() {
|
||||
decoder.claim_container_read::<T>(len)?;
|
||||
// optimize for reading u8 vecs
|
||||
let mut vec = Vec::new();
|
||||
vec.resize(len, 0u8);
|
||||
decoder.reader().read(&mut vec)?;
|
||||
// Safety: Vec<T> is Vec<u8>
|
||||
Ok(unsafe { core::mem::transmute(vec) })
|
||||
} else {
|
||||
decoder.claim_container_read::<T>(len)?;
|
||||
|
||||
let mut vec = Vec::with_capacity(len);
|
||||
for _ in 0..len {
|
||||
// See the documentation on `unclaim_bytes_read` as to why we're doing this here
|
||||
decoder.unclaim_bytes_read(core::mem::size_of::<T>());
|
||||
let mut vec = Vec::with_capacity(len);
|
||||
for _ in 0..len {
|
||||
// See the documentation on `unclaim_bytes_read` as to why we're doing this here
|
||||
decoder.unclaim_bytes_read(core::mem::size_of::<T>());
|
||||
|
||||
vec.push(T::decode(decoder)?);
|
||||
vec.push(T::decode(decoder)?);
|
||||
}
|
||||
Ok(vec)
|
||||
}
|
||||
Ok(vec)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -314,34 +284,47 @@ where
|
|||
{
|
||||
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||
let len = crate::de::decode_slice_len(decoder)?;
|
||||
decoder.claim_container_read::<T>(len)?;
|
||||
|
||||
let mut vec = Vec::with_capacity(len);
|
||||
for _ in 0..len {
|
||||
// See the documentation on `unclaim_bytes_read` as to why we're doing this here
|
||||
decoder.unclaim_bytes_read(core::mem::size_of::<T>());
|
||||
if unty::type_equal::<T, u8>() {
|
||||
decoder.claim_container_read::<T>(len)?;
|
||||
// optimize for reading u8 vecs
|
||||
let mut vec = Vec::new();
|
||||
vec.resize(len, 0u8);
|
||||
decoder.reader().read(&mut vec)?;
|
||||
// Safety: Vec<T> is Vec<u8>
|
||||
Ok(unsafe { core::mem::transmute(vec) })
|
||||
} else {
|
||||
decoder.claim_container_read::<T>(len)?;
|
||||
|
||||
vec.push(T::borrow_decode(decoder)?);
|
||||
let mut vec = Vec::with_capacity(len);
|
||||
for _ in 0..len {
|
||||
// See the documentation on `unclaim_bytes_read` as to why we're doing this here
|
||||
decoder.unclaim_bytes_read(core::mem::size_of::<T>());
|
||||
|
||||
vec.push(T::borrow_decode(decoder)?);
|
||||
}
|
||||
Ok(vec)
|
||||
}
|
||||
Ok(vec)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Encode for Vec<T>
|
||||
where
|
||||
T: Encode + 'static,
|
||||
T: Encode,
|
||||
{
|
||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||
crate::enc::encode_slice_len(encoder, self.len())?;
|
||||
if core::any::TypeId::of::<T>() == core::any::TypeId::of::<u8>() {
|
||||
if unty::type_equal::<T, u8>() {
|
||||
// Safety: T == u8
|
||||
let slice: &[u8] = unsafe { core::mem::transmute(self.as_slice()) };
|
||||
encoder.writer().write(slice)?;
|
||||
return Ok(());
|
||||
Ok(())
|
||||
} else {
|
||||
for item in self.iter() {
|
||||
item.encode(encoder)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
for item in self.iter() {
|
||||
item.encode(encoder)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue