move to custom read implementation for deserialize_in_place
This commit is contained in:
parent
68ca894b81
commit
76b7662dcd
|
|
@ -18,9 +18,9 @@ description = "A binary serialization / deserialization strategy that uses Serde
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = "1.2.0"
|
byteorder = "1.2.0"
|
||||||
serde = "1.0.27"
|
serde = "^1.0.27"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_bytes = "0.10.3"
|
serde_bytes = "^0.10.3"
|
||||||
serde_derive = "1.0.27"
|
serde_derive = "^1.0.27"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -258,7 +258,11 @@ impl Config {
|
||||||
/// TODO: document
|
/// TODO: document
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn deserialize_in_place<'a, T: serde::de::Deserialize<'a>>(&self, reader: &'a [u8], place: &mut T) -> Result<()> {
|
pub fn deserialize_in_place<'a, R, T: >(&self, reader: R, place: &mut T) -> Result<()>
|
||||||
|
where
|
||||||
|
R: BincodeRead<'a>,
|
||||||
|
T: serde::de::Deserialize<'a>
|
||||||
|
{
|
||||||
config_map!(self, opts => ::internal::deserialize_in_place(reader, opts, place))
|
config_map!(self, opts => ::internal::deserialize_in_place(reader, opts, place))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -93,17 +93,12 @@ where
|
||||||
serde::Deserialize::deserialize(&mut deserializer)
|
serde::Deserialize::deserialize(&mut deserializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn deserialize_in_place<'a, T, O>(
|
pub(crate) fn deserialize_in_place<'a, R, T, O>(reader: R, options: O, place: &mut T) -> Result<()>
|
||||||
bytes: &'a [u8],
|
|
||||||
options: O,
|
|
||||||
place: &mut T,
|
|
||||||
) -> Result<()>
|
|
||||||
where
|
where
|
||||||
|
R: BincodeRead<'a>,
|
||||||
T: serde::de::Deserialize<'a>,
|
T: serde::de::Deserialize<'a>,
|
||||||
O: Options,
|
O: Options,
|
||||||
{
|
{
|
||||||
let reader = ::de::read::SliceReader::new(bytes);
|
|
||||||
let options = ::config::WithOtherLimit::new(options, Infinite);
|
|
||||||
let mut deserializer = ::de::Deserializer::<_, _>::new(reader, options);
|
let mut deserializer = ::de::Deserializer::<_, _>::new(reader, options);
|
||||||
serde::Deserialize::deserialize_in_place(&mut deserializer, place)
|
serde::Deserialize::deserialize_in_place(&mut deserializer, place)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,11 +114,12 @@ where
|
||||||
|
|
||||||
/// TODO: document
|
/// TODO: document
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn deserialize_in_place<'a, T>(bytes: &'a[u8], place: &mut T) -> Result<()>
|
pub fn deserialize_in_place<'a, R, T>(reader: R, place: &mut T) -> Result<()>
|
||||||
where
|
where
|
||||||
T: serde::de::Deserialize<'a>,
|
T: serde::de::Deserialize<'a>,
|
||||||
|
R: BincodeRead<'a>
|
||||||
{
|
{
|
||||||
config().deserialize_in_place(bytes, place)
|
config().deserialize_in_place(reader, place)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserializes a slice of bytes into an instance of `T` using the default configuration.
|
/// Deserializes a slice of bytes into an instance of `T` using the default configuration.
|
||||||
|
|
|
||||||
|
|
@ -466,6 +466,80 @@ fn test_zero_copy_parse() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_zero_copy_parse_deserialize_into() {
|
fn test_zero_copy_parse_deserialize_into() {
|
||||||
|
use bincode::BincodeRead;
|
||||||
|
use std::io;
|
||||||
|
|
||||||
|
/// A BincodeRead implementation for byte slices
|
||||||
|
pub struct SliceReader<'storage> {
|
||||||
|
slice: &'storage [u8],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'storage> SliceReader<'storage> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn unexpected_eof() -> Box<::ErrorKind> {
|
||||||
|
return Box::new(::ErrorKind::Io(
|
||||||
|
io::Error::new(io::ErrorKind::UnexpectedEof, ""),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'storage> io::Read for SliceReader<'storage> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
|
||||||
|
(&mut self.slice).read(out)
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn read_exact(&mut self, out: &mut [u8]) -> io::Result<()> {
|
||||||
|
(&mut self.slice).read_exact(out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'storage> BincodeRead<'storage> for SliceReader<'storage> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn forward_read_str<V>(&mut self, length: usize, visitor: V) -> Result<V::Value>
|
||||||
|
where
|
||||||
|
V: serde::de::Visitor<'storage>,
|
||||||
|
{
|
||||||
|
use ErrorKind;
|
||||||
|
if length > self.slice.len() {
|
||||||
|
return Err(SliceReader::unexpected_eof());
|
||||||
|
}
|
||||||
|
|
||||||
|
let string = match ::std::str::from_utf8(&self.slice[..length]) {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(e) => return Err(ErrorKind::InvalidUtf8Encoding(e).into()),
|
||||||
|
};
|
||||||
|
let r = visitor.visit_borrowed_str(string);
|
||||||
|
self.slice = &self.slice[length..];
|
||||||
|
r
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn get_byte_buffer(&mut self, length: usize) -> Result<Vec<u8>> {
|
||||||
|
if length > self.slice.len() {
|
||||||
|
return Err(SliceReader::unexpected_eof());
|
||||||
|
}
|
||||||
|
|
||||||
|
let r = &self.slice[..length];
|
||||||
|
self.slice = &self.slice[length..];
|
||||||
|
Ok(r.to_vec())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn forward_read_bytes<V>(&mut self, length: usize, visitor: V) -> Result<V::Value>
|
||||||
|
where
|
||||||
|
V: serde::de::Visitor<'storage>,
|
||||||
|
{
|
||||||
|
if length > self.slice.len() {
|
||||||
|
return Err(SliceReader::unexpected_eof());
|
||||||
|
}
|
||||||
|
|
||||||
|
let r = visitor.visit_borrowed_bytes(&self.slice[..length]);
|
||||||
|
self.slice = &self.slice[length..];
|
||||||
|
r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
|
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
|
||||||
struct Foo<'a> {
|
struct Foo<'a> {
|
||||||
borrowed_str: &'a str,
|
borrowed_str: &'a str,
|
||||||
|
|
@ -483,7 +557,12 @@ fn test_zero_copy_parse_deserialize_into() {
|
||||||
borrowed_str: "hello",
|
borrowed_str: "hello",
|
||||||
borrowed_bytes: &[10, 11, 12, 13],
|
borrowed_bytes: &[10, 11, 12, 13],
|
||||||
};
|
};
|
||||||
deserialize_in_place(&encoded[..], &mut target).unwrap();
|
deserialize_in_place(
|
||||||
|
SliceReader {
|
||||||
|
slice: &encoded[..],
|
||||||
|
},
|
||||||
|
&mut target,
|
||||||
|
).unwrap();
|
||||||
assert_eq!(target, f);
|
assert_eq!(target, f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue