add deserialize_in_place

This commit is contained in:
Ty Overby 2018-02-07 18:24:47 -08:00
parent b31151a605
commit 68ca894b81
5 changed files with 67 additions and 6 deletions

View File

@ -18,9 +18,9 @@ description = "A binary serialization / deserialization strategy that uses Serde
[dependencies]
byteorder = "1.2.0"
serde = "1.0.16"
serde = "1.0.27"
[dev-dependencies]
serde_bytes = "0.10.*"
serde_derive = "1.0.16"
serde_bytes = "0.10.3"
serde_derive = "1.0.27"

View File

@ -255,6 +255,13 @@ impl Config {
config_map!(self, opts => ::internal::deserialize(bytes, opts))
}
/// TODO: document
#[doc(hidden)]
#[inline(always)]
pub fn deserialize_in_place<'a, T: serde::de::Deserialize<'a>>(&self, reader: &'a [u8], place: &mut T) -> Result<()> {
config_map!(self, opts => ::internal::deserialize_in_place(reader, opts, place))
}
/// Deserializes an object directly from a `Read`er using this configuration
///
/// If this returns an `Error`, `reader` may be in an invalid state.

View File

@ -93,6 +93,21 @@ where
serde::Deserialize::deserialize(&mut deserializer)
}
pub(crate) fn deserialize_in_place<'a, T, O>(
bytes: &'a [u8],
options: O,
place: &mut T,
) -> Result<()>
where
T: serde::de::Deserialize<'a>,
O: Options,
{
let reader = ::de::read::SliceReader::new(bytes);
let options = ::config::WithOtherLimit::new(options, Infinite);
let mut deserializer = ::de::Deserializer::<_, _>::new(reader, options);
serde::Deserialize::deserialize_in_place(&mut deserializer, place)
}
pub(crate) fn deserialize<'a, T, O>(bytes: &'a [u8], options: O) -> Result<T>
where
T: serde::de::Deserialize<'a>,

View File

@ -112,6 +112,15 @@ where
config().deserialize_from_custom(reader)
}
/// TODO: document
#[doc(hidden)]
pub fn deserialize_in_place<'a, T>(bytes: &'a[u8], place: &mut T) -> Result<()>
where
T: serde::de::Deserialize<'a>,
{
config().deserialize_in_place(bytes, place)
}
/// Deserializes a slice of bytes into an instance of `T` using the default configuration.
pub fn deserialize<'a, T>(bytes: &'a [u8]) -> Result<T>
where

View File

@ -10,7 +10,8 @@ use std::fmt::Debug;
use std::collections::HashMap;
use std::borrow::Cow;
use bincode::{config, deserialize, deserialize_from, serialize, serialized_size, ErrorKind, Result};
use bincode::{config, deserialize, deserialize_from, deserialize_in_place, serialize,
serialized_size, ErrorKind, Result};
fn the_same<V>(element: V)
where
@ -315,7 +316,9 @@ fn test_serialized_size_bounded() {
assert!(
config()
.limit(8 + 3 * 4 - 1)
.serialized_size(&vec![0u32, 1u32, 2u32]).is_err());
.serialized_size(&vec![0u32, 1u32, 2u32])
.is_err()
);
}
#[test]
@ -461,11 +464,38 @@ fn test_zero_copy_parse() {
}
}
#[test]
fn test_zero_copy_parse_deserialize_into() {
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
struct Foo<'a> {
borrowed_str: &'a str,
borrowed_bytes: &'a [u8],
}
let f = Foo {
borrowed_str: "hi",
borrowed_bytes: &[0, 1, 2, 3],
};
{
let encoded = serialize(&f).unwrap();
let mut target = Foo {
borrowed_str: "hello",
borrowed_bytes: &[10, 11, 12, 13],
};
deserialize_in_place(&encoded[..], &mut target).unwrap();
assert_eq!(target, f);
}
}
#[test]
fn not_human_readable() {
use std::net::Ipv4Addr;
let ip = Ipv4Addr::new(1, 2, 3, 4);
the_same(ip);
assert_eq!(&ip.octets()[..], &serialize(&ip).unwrap()[..]);
assert_eq!(::std::mem::size_of::<Ipv4Addr>() as u64, serialized_size(&ip).unwrap());
assert_eq!(
::std::mem::size_of::<Ipv4Addr>() as u64,
serialized_size(&ip).unwrap()
);
}