Skip to content

Commit

Permalink
Made all decode_from_slice also return the number of bytes read
Browse files Browse the repository at this point in the history
  • Loading branch information
VictorKoenders committed Dec 9, 2021
1 parent d3a51a9 commit d4a8533
Show file tree
Hide file tree
Showing 16 changed files with 88 additions and 47 deletions.
8 changes: 4 additions & 4 deletions benches/varint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ fn slice_varint_u8(c: &mut Criterion) {

c.bench_function("slice_varint_u8", |b| {
b.iter(|| {
let _: Vec<u8> = bincode::decode_from_slice(&bytes, config).unwrap();
let _: (Vec<u8>, usize) = bincode::decode_from_slice(&bytes, config).unwrap();
})
});
}
Expand All @@ -30,7 +30,7 @@ fn slice_varint_u16(c: &mut Criterion) {

c.bench_function("slice_varint_u16", |b| {
b.iter(|| {
let _: Vec<u16> = bincode::decode_from_slice(&bytes, config).unwrap();
let _: (Vec<u8>, usize) = bincode::decode_from_slice(&bytes, config).unwrap();
})
});
}
Expand All @@ -46,7 +46,7 @@ fn slice_varint_u32(c: &mut Criterion) {

c.bench_function("slice_varint_u32", |b| {
b.iter(|| {
let _: Vec<u32> = bincode::decode_from_slice(&bytes, config).unwrap();
let _: (Vec<u16>, usize) = bincode::decode_from_slice(&bytes, config).unwrap();
})
});
}
Expand All @@ -62,7 +62,7 @@ fn slice_varint_u64(c: &mut Criterion) {

c.bench_function("slice_varint_u64", |b| {
b.iter(|| {
let _: Vec<u64> = bincode::decode_from_slice(&bytes, config).unwrap();
let _: (Vec<u64>, usize) = bincode::decode_from_slice(&bytes, config).unwrap();
})
});
}
Expand Down
12 changes: 6 additions & 6 deletions derive/src/derive_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ impl DeriveStruct {
fn_body
.push_parsed(format!(
"bincode::Encode::encode(&bincode::serde::Compat(&self.{}), &mut encoder)?;",
field.to_string()
field
))
.unwrap();
} else {
fn_body
.push_parsed(format!(
"bincode::enc::Encode::encode(&self.{}, &mut encoder)?;",
field.to_string()
field
))
.unwrap();
}
Expand Down Expand Up @@ -72,14 +72,14 @@ impl DeriveStruct {
struct_body
.push_parsed(format!(
"{}: (<bincode::serde::Compat<_> as bincode::Decode>::decode(&mut decoder)?).0,",
field.to_string()
field
))
.unwrap();
} else {
struct_body
.push_parsed(format!(
"{}: bincode::Decode::decode(&mut decoder)?,",
field.to_string()
field
))
.unwrap();
}
Expand Down Expand Up @@ -114,14 +114,14 @@ impl DeriveStruct {
struct_body
.push_parsed(format!(
"{}: (<bincode::serde::BorrowCompat<_> as bincode::de::BorrowDecode>::borrow_decode(&mut decoder)?).0,",
field.to_string()
field
))
.unwrap();
} else {
struct_body
.push_parsed(format!(
"{}: bincode::de::BorrowDecode::borrow_decode(&mut decoder)?,",
field.to_string()
field
))
.unwrap();
}
Expand Down
1 change: 1 addition & 0 deletions derive/src/parse/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ impl Generics {
}

#[derive(Debug)]
#[allow(clippy::enum_variant_names)]
enum Generic {
Lifetime(Lifetime),
Generic(SimpleGeneric),
Expand Down
3 changes: 2 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,10 @@ fn main() {
// The 4 floats are encoded in 4 bytes each.
assert_eq!(encoded.len(), 1 + 4 * 4);

let decoded: World = bincode::decode_from_slice(&encoded[..], config).unwrap();
let (decoded, len): (World, usize) = bincode::decode_from_slice(&encoded[..], config).unwrap();

assert_eq!(world, decoded);
assert_eq!(len, encoded.len()); // read all bytes
}
```

Expand Down
1 change: 1 addition & 0 deletions src/de/impl_core.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![allow(unused_unsafe)]
#![allow(clippy::needless_borrow)]

//! Contains implementations for rust core that have not been stabilized
//!
Expand Down
2 changes: 1 addition & 1 deletion src/de/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ pub trait BorrowReader<'storage>: Reader {

/// A reader type for `&[u8]` slices. Implements both [Reader] and [BorrowReader], and thus can be used for borrowed data.
pub struct SliceReader<'storage> {
slice: &'storage [u8],
pub(crate) slice: &'storage [u8],
}

impl<'storage> SliceReader<'storage> {
Expand Down
2 changes: 1 addition & 1 deletion src/enc/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl<'storage> Writer for SliceWriter<'storage> {
if bytes.len() > self.slice.len() {
return Err(EncodeError::UnexpectedEnd);
}
let (a, b) = core::mem::replace(&mut self.slice, &mut []).split_at_mut(bytes.len());
let (a, b) = core::mem::take(&mut self.slice).split_at_mut(bytes.len());
a.copy_from_slice(bytes);
self.slice = b;

Expand Down
8 changes: 5 additions & 3 deletions src/features/serde/de_owned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,22 @@ use crate::{
};
use serde_incl::de::*;

/// Decode an owned type from the given slice.
/// Decode an owned type from the given slice. Will return the decoded type `T` as well as the amount of bytes that were read.
///
/// Note that this does not work with borrowed types like `&str` or `&[u8]`. For that use [decode_borrowed_from_slice].
///
/// [decode_borrowed_from_slice]: fn.decode_borrowed_from_slice.html
pub fn decode_from_slice<T, C>(slice: &[u8], config: C) -> Result<T, DecodeError>
pub fn decode_from_slice<T, C>(slice: &[u8], config: C) -> Result<(T, usize), DecodeError>
where
T: DeserializeOwned,
C: Config,
{
let reader = crate::de::read::SliceReader::new(slice);
let mut decoder = crate::de::DecoderImpl::new(reader, config);
let serde_decoder = SerdeDecoder { de: &mut decoder };
T::deserialize(serde_decoder)
let result = T::deserialize(serde_decoder)?;
let bytes_read = slice.len() - decoder.reader().slice.len();
Ok((result, bytes_read))
}

pub(crate) struct SerdeDecoder<'a, DE: Decoder> {
Expand Down
11 changes: 6 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,14 @@
//!
//! // Decoding works the same as encoding.
//! // The trait used is `de::Decode`, and can also be automatically implemented with the `derive` feature.
//! let decoded: (u8, u32, i128, char, [u8; 4]) = bincode::decode_from_slice(slice, Configuration::standard()).unwrap();
//! let decoded: (u8, u32, i128, char, [u8; 4]) = bincode::decode_from_slice(slice, Configuration::standard()).unwrap().0;
//!
//! assert_eq!(decoded, input);
//! ```

#![doc(html_root_url = "https://docs.rs/bincode/2.0.0-alpha.1")]
#![crate_name = "bincode"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]

#[cfg(feature = "alloc")]
extern crate alloc;
Expand All @@ -68,7 +67,7 @@ mod features;
pub(crate) mod utils;
pub(crate) mod varint;

use de::read::Reader;
use de::{read::Reader, Decoder};
use enc::write::Writer;
pub use features::*;

Expand Down Expand Up @@ -121,10 +120,12 @@ pub fn encode_into_writer<E: enc::Encode, W: Writer, C: Config>(
pub fn decode_from_slice<'a, D: de::BorrowDecode<'a>, C: Config>(
src: &'a [u8],
config: C,
) -> Result<D, error::DecodeError> {
) -> Result<(D, usize), error::DecodeError> {
let reader = de::read::SliceReader::new(src);
let mut decoder = de::DecoderImpl::<_, C>::new(reader, config);
D::borrow_decode(&mut decoder)
let result = D::borrow_decode(&mut decoder)?;
let bytes_read = src.len() - decoder.reader().slice.len();
Ok((result, bytes_read))
}

/// Attempt to decode a given type `D` from the given [Reader].
Expand Down
4 changes: 3 additions & 1 deletion tests/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ fn test_vec() {
let vec = bincode::encode_to_vec(Foo { a: 5, b: 10 }, Configuration::standard()).unwrap();
assert_eq!(vec, &[5, 10]);

let foo: Foo = bincode::decode_from_slice(&vec, Configuration::standard()).unwrap();
let (foo, len): (Foo, usize) =
bincode::decode_from_slice(&vec, Configuration::standard()).unwrap();
assert_eq!(foo.a, 5);
assert_eq!(foo.b, 10);
assert_eq!(len, 2);
}

#[test]
Expand Down
9 changes: 6 additions & 3 deletions tests/basic_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,10 @@ fn test_slice() {
bincode::encode_into_slice(input, &mut buffer, Configuration::standard()).unwrap();
assert_eq!(&buffer[..8], &[7, 1, 2, 3, 4, 5, 6, 7]);

let output: &[u8] =
let (output, len): (&[u8], usize) =
bincode::decode_from_slice(&mut buffer[..8], Configuration::standard()).unwrap();
assert_eq!(input, output);
assert_eq!(len, 8);
}

#[test]
Expand All @@ -151,9 +152,10 @@ fn test_str() {
&[11, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]
);

let output: &str =
let (output, len): (&str, usize) =
bincode::decode_from_slice(&mut buffer[..12], Configuration::standard()).unwrap();
assert_eq!(input, output);
assert_eq!(len, 12);
}

#[test]
Expand All @@ -163,7 +165,8 @@ fn test_array() {
bincode::encode_into_slice(input, &mut buffer, Configuration::standard()).unwrap();
assert_eq!(&buffer[..10], &[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]);

let output: [u8; 10] =
let (output, len): ([u8; 10], usize) =
bincode::decode_from_slice(&mut buffer[..10], Configuration::standard()).unwrap();
assert_eq!(input, output);
assert_eq!(len, 10);
}
25 changes: 18 additions & 7 deletions tests/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,10 @@ fn test_decode() {
c: 1024u32,
};
let slice = [5, 10, 251, 0, 4];
let result: Test2<u32> = bincode::decode_from_slice(&slice, Configuration::standard()).unwrap();
let (result, len): (Test2<u32>, usize) =
bincode::decode_from_slice(&slice, Configuration::standard()).unwrap();
assert_eq!(result, start);
assert_eq!(len, 5);
}

#[test]
Expand All @@ -77,8 +79,11 @@ fn test_encode_decode_str() {
let mut slice = [0u8; 100];

let len = bincode::encode_into_slice(&start, &mut slice, Configuration::standard()).unwrap();
let end: Test3 = bincode::decode_from_slice(&slice[..len], Configuration::standard()).unwrap();
assert_eq!(len, 12);
let (end, len): (Test3, usize) =
bincode::decode_from_slice(&slice[..len], Configuration::standard()).unwrap();
assert_eq!(end, start);
assert_eq!(len, 12);
}

#[test]
Expand All @@ -95,9 +100,10 @@ fn test_encode_tuple() {
fn test_decode_tuple() {
let start = TestTupleStruct(5, 10, 1024);
let mut slice = [5, 10, 251, 0, 4];
let result: TestTupleStruct =
let (result, len): (TestTupleStruct, usize) =
bincode::decode_from_slice(&mut slice, Configuration::standard()).unwrap();
assert_eq!(result, start);
assert_eq!(len, 5);
}

#[test]
Expand All @@ -114,9 +120,10 @@ fn test_encode_enum_struct_variant() {
fn test_decode_enum_struct_variant() {
let start = TestEnum::Bar { name: 5u32 };
let mut slice = [1, 5];
let result: TestEnum =
let (result, len): (TestEnum, usize) =
bincode::decode_from_slice(&mut slice, Configuration::standard()).unwrap();
assert_eq!(result, start);
assert_eq!(len, 2);
}

#[test]
Expand All @@ -133,9 +140,10 @@ fn test_encode_enum_tuple_variant() {
fn test_decode_enum_unit_variant() {
let start = TestEnum::Foo;
let mut slice = [0];
let result: TestEnum =
let (result, len): (TestEnum, usize) =
bincode::decode_from_slice(&mut slice, Configuration::standard()).unwrap();
assert_eq!(result, start);
assert_eq!(len, 1);
}

#[test]
Expand All @@ -152,9 +160,10 @@ fn test_encode_enum_unit_variant() {
fn test_decode_enum_tuple_variant() {
let start = TestEnum::Baz(5, 10, 1024);
let mut slice = [2, 5, 10, 251, 0, 4];
let result: TestEnum =
let (result, len): (TestEnum, usize) =
bincode::decode_from_slice(&mut slice, Configuration::standard()).unwrap();
assert_eq!(result, start);
assert_eq!(len, 6);
}

#[derive(bincode::Decode, bincode::Encode, PartialEq, Eq, Debug)]
Expand Down Expand Up @@ -183,7 +192,9 @@ fn test_c_style_enum() {
assert_eq!(ser(CStyleEnum::E), 6);

fn de(num: u8) -> Result<CStyleEnum, bincode::error::DecodeError> {
bincode::decode_from_slice(&[num], Configuration::standard())
let (result, len) = bincode::decode_from_slice(&[num], Configuration::standard())?;
assert_eq!(len, 1);
Ok(result)
}

fn expected_err(idx: u32) -> Result<CStyleEnum, bincode::error::DecodeError> {
Expand Down
4 changes: 3 additions & 1 deletion tests/issues/issue_431.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ fn test() {
};
let vec = bincode::encode_to_vec(&t, Configuration::standard()).unwrap();

let decoded: T<String> = bincode::decode_from_slice(&vec, Configuration::standard()).unwrap();
let (decoded, len): (T<String>, usize) =
bincode::decode_from_slice(&vec, Configuration::standard()).unwrap();

assert_eq!(t, decoded);
assert_eq!(len, 12);
}
Loading

0 comments on commit d4a8533

Please sign in to comment.