Skip to content

Commit 2cfe21d

Browse files
Made all decode_from_slice also return the number of bytes read
1 parent 882e227 commit 2cfe21d

File tree

14 files changed

+81
-39
lines changed

14 files changed

+81
-39
lines changed

benches/varint.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fn slice_varint_u8(c: &mut Criterion) {
1414

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

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

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

6363
c.bench_function("slice_varint_u64", |b| {
6464
b.iter(|| {
65-
let _: Vec<u64> = bincode::decode_from_slice(&bytes, config).unwrap();
65+
let _: (Vec<u64>, usize) = bincode::decode_from_slice(&bytes, config).unwrap();
6666
})
6767
});
6868
}

derive/src/parse/generics.rs

+1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ impl Generics {
122122
}
123123

124124
#[derive(Debug)]
125+
#[allow(clippy::enum_variant_names)]
125126
enum Generic {
126127
Lifetime(Lifetime),
127128
Simple(SimpleGeneric),

readme.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,10 @@ fn main() {
5353
// The 4 floats are encoded in 4 bytes each.
5454
assert_eq!(encoded.len(), 1 + 4 * 4);
5555

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

5858
assert_eq!(world, decoded);
59+
assert_eq!(len, encoded.len()); // read all bytes
5960
}
6061
```
6162

src/de/impl_core.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![allow(unused_unsafe)]
2+
#![allow(clippy::needless_borrow)]
23

34
//! Contains implementations for rust core that have not been stabilized
45
//!

src/de/read.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ pub trait BorrowReader<'storage>: Reader {
6161

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

6767
impl<'storage> SliceReader<'storage> {

src/features/serde/de_owned.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,22 @@ use crate::{
55
};
66
use serde_incl::de::*;
77

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

2426
pub(crate) struct SerdeDecoder<'a, DE: Decoder> {

src/lib.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
//!
5050
//! // Decoding works the same as encoding.
5151
//! // The trait used is `de::Decode`, and can also be automatically implemented with the `derive` feature.
52-
//! let decoded: (u8, u32, i128, char, [u8; 4]) = bincode::decode_from_slice(slice, Configuration::standard()).unwrap();
52+
//! let decoded: (u8, u32, i128, char, [u8; 4]) = bincode::decode_from_slice(slice, Configuration::standard()).unwrap().0;
5353
//!
5454
//! assert_eq!(decoded, input);
5555
//! ```
@@ -67,7 +67,7 @@ mod features;
6767
pub(crate) mod utils;
6868
pub(crate) mod varint;
6969

70-
use de::read::Reader;
70+
use de::{read::Reader, Decoder};
7171
use enc::write::Writer;
7272
pub use features::*;
7373

@@ -120,10 +120,12 @@ pub fn encode_into_writer<E: enc::Encode, W: Writer, C: Config>(
120120
pub fn decode_from_slice<'a, D: de::BorrowDecode<'a>, C: Config>(
121121
src: &'a [u8],
122122
config: C,
123-
) -> Result<D, error::DecodeError> {
123+
) -> Result<(D, usize), error::DecodeError> {
124124
let reader = de::read::SliceReader::new(src);
125125
let mut decoder = de::DecoderImpl::<_, C>::new(reader, config);
126-
D::borrow_decode(&mut decoder)
126+
let result = D::borrow_decode(&mut decoder)?;
127+
let bytes_read = src.len() - decoder.reader().slice.len();
128+
Ok((result, bytes_read))
127129
}
128130

129131
/// Attempt to decode a given type `D` from the given [Reader].

tests/alloc.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,11 @@ fn test_vec() {
4444
let vec = bincode::encode_to_vec(Foo { a: 5, b: 10 }, Configuration::standard()).unwrap();
4545
assert_eq!(vec, &[5, 10]);
4646

47-
let foo: Foo = bincode::decode_from_slice(&vec, Configuration::standard()).unwrap();
47+
let (foo, len): (Foo, usize) =
48+
bincode::decode_from_slice(&vec, Configuration::standard()).unwrap();
4849
assert_eq!(foo.a, 5);
4950
assert_eq!(foo.b, 10);
51+
assert_eq!(len, 2);
5052
}
5153

5254
#[test]

tests/basic_types.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,10 @@ fn test_slice() {
136136
bincode::encode_into_slice(input, &mut buffer, Configuration::standard()).unwrap();
137137
assert_eq!(&buffer[..8], &[7, 1, 2, 3, 4, 5, 6, 7]);
138138

139-
let output: &[u8] =
139+
let (output, len): (&[u8], usize) =
140140
bincode::decode_from_slice(&mut buffer[..8], Configuration::standard()).unwrap();
141141
assert_eq!(input, output);
142+
assert_eq!(len, 8);
142143
}
143144

144145
#[test]
@@ -172,9 +173,10 @@ fn test_str() {
172173
&[11, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]
173174
);
174175

175-
let output: &str =
176+
let (output, len): (&str, usize) =
176177
bincode::decode_from_slice(&mut buffer[..12], Configuration::standard()).unwrap();
177178
assert_eq!(input, output);
179+
assert_eq!(len, 12);
178180
}
179181

180182
#[test]
@@ -208,7 +210,8 @@ fn test_array() {
208210
bincode::encode_into_slice(input, &mut buffer, Configuration::standard()).unwrap();
209211
assert_eq!(&buffer[..10], &[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]);
210212

211-
let output: [u8; 10] =
213+
let (output, len): ([u8; 10], usize) =
212214
bincode::decode_from_slice(&mut buffer[..10], Configuration::standard()).unwrap();
213215
assert_eq!(input, output);
216+
assert_eq!(len, 10);
214217
}

tests/derive.rs

+18-7
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,10 @@ fn test_decode() {
6464
c: 1024u32,
6565
};
6666
let slice = [5, 10, 251, 0, 4];
67-
let result: Test2<u32> = bincode::decode_from_slice(&slice, Configuration::standard()).unwrap();
67+
let (result, len): (Test2<u32>, usize) =
68+
bincode::decode_from_slice(&slice, Configuration::standard()).unwrap();
6869
assert_eq!(result, start);
70+
assert_eq!(len, 5);
6971
}
7072

7173
#[test]
@@ -79,8 +81,11 @@ fn test_encode_decode_str() {
7981
let mut slice = [0u8; 100];
8082

8183
let len = bincode::encode_into_slice(&start, &mut slice, Configuration::standard()).unwrap();
82-
let end: Test3 = bincode::decode_from_slice(&slice[..len], Configuration::standard()).unwrap();
84+
assert_eq!(len, 12);
85+
let (end, len): (Test3, usize) =
86+
bincode::decode_from_slice(&slice[..len], Configuration::standard()).unwrap();
8387
assert_eq!(end, start);
88+
assert_eq!(len, 12);
8489
}
8590

8691
#[test]
@@ -97,9 +102,10 @@ fn test_encode_tuple() {
97102
fn test_decode_tuple() {
98103
let start = TestTupleStruct(5, 10, 1024);
99104
let mut slice = [5, 10, 251, 0, 4];
100-
let result: TestTupleStruct =
105+
let (result, len): (TestTupleStruct, usize) =
101106
bincode::decode_from_slice(&mut slice, Configuration::standard()).unwrap();
102107
assert_eq!(result, start);
108+
assert_eq!(len, 5);
103109
}
104110

105111
#[test]
@@ -116,9 +122,10 @@ fn test_encode_enum_struct_variant() {
116122
fn test_decode_enum_struct_variant() {
117123
let start = TestEnum::Bar { name: 5u32 };
118124
let mut slice = [1, 5];
119-
let result: TestEnum =
125+
let (result, len): (TestEnum, usize) =
120126
bincode::decode_from_slice(&mut slice, Configuration::standard()).unwrap();
121127
assert_eq!(result, start);
128+
assert_eq!(len, 2);
122129
}
123130

124131
#[test]
@@ -135,9 +142,10 @@ fn test_encode_enum_tuple_variant() {
135142
fn test_decode_enum_unit_variant() {
136143
let start = TestEnum::Foo;
137144
let mut slice = [0];
138-
let result: TestEnum =
145+
let (result, len): (TestEnum, usize) =
139146
bincode::decode_from_slice(&mut slice, Configuration::standard()).unwrap();
140147
assert_eq!(result, start);
148+
assert_eq!(len, 1);
141149
}
142150

143151
#[test]
@@ -154,9 +162,10 @@ fn test_encode_enum_unit_variant() {
154162
fn test_decode_enum_tuple_variant() {
155163
let start = TestEnum::Baz(5, 10, 1024);
156164
let mut slice = [2, 5, 10, 251, 0, 4];
157-
let result: TestEnum =
165+
let (result, len): (TestEnum, usize) =
158166
bincode::decode_from_slice(&mut slice, Configuration::standard()).unwrap();
159167
assert_eq!(result, start);
168+
assert_eq!(len, 6);
160169
}
161170

162171
#[derive(bincode::Decode, bincode::Encode, PartialEq, Eq, Debug)]
@@ -185,7 +194,9 @@ fn test_c_style_enum() {
185194
assert_eq!(ser(CStyleEnum::E), 6);
186195

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

191202
fn expected_err(idx: u32) -> Result<CStyleEnum, bincode::error::DecodeError> {

tests/issues/issue_431.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ fn test() {
2626
};
2727
let vec = bincode::encode_to_vec(&t, Configuration::standard()).unwrap();
2828

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

3132
assert_eq!(t, decoded);
33+
assert_eq!(len, 12);
3234
}

tests/serde.rs

+22-11
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ fn test_serde_round_trip() {
2828
let bytes =
2929
bincode::encode_to_vec(SerdeRoundtrip { a: 15, b: 15 }, Configuration::standard()).unwrap();
3030
assert_eq!(bytes, &[15, 15]);
31-
let result: SerdeRoundtrip =
31+
let (result, len): (SerdeRoundtrip, usize) =
3232
bincode::decode_from_slice(&bytes, Configuration::standard()).unwrap();
3333
assert_eq!(result.a, 15);
3434
assert_eq!(result.b, 15);
35+
assert_eq!(len, 2);
3536
}
3637

3738
#[derive(Serialize, Deserialize, PartialEq, Debug)]
@@ -115,7 +116,7 @@ fn test_serialize_deserialize_owned_data() {
115116

116117
assert_eq!(result, expected);
117118

118-
let output: SerdeWithOwnedData =
119+
let (output, len): (SerdeWithOwnedData, usize) =
119120
bincode::serde::decode_from_slice(&result, Configuration::standard()).unwrap();
120121
assert_eq!(
121122
SerdeWithOwnedData {
@@ -124,6 +125,7 @@ fn test_serialize_deserialize_owned_data() {
124125
},
125126
output
126127
);
128+
assert_eq!(len, 13);
127129
}
128130

129131
#[cfg(feature = "derive")]
@@ -154,24 +156,33 @@ mod derive {
154156

155157
#[test]
156158
fn test_serde_derive() {
157-
fn test_encode_decode<T>(start: T)
159+
fn test_encode_decode<T>(start: T, expected_len: usize)
158160
where
159161
T: bincode::Encode + bincode::Decode + PartialEq + core::fmt::Debug,
160162
{
161163
let mut slice = [0u8; 100];
162164
let len =
163165
bincode::encode_into_slice(&start, &mut slice, Configuration::standard()).unwrap();
166+
assert_eq!(len, expected_len);
164167
let slice = &slice[..len];
165-
let result: T = bincode::decode_from_slice(&slice, Configuration::standard()).unwrap();
168+
let (result, len): (T, usize) =
169+
bincode::decode_from_slice(&slice, Configuration::standard()).unwrap();
166170

167171
assert_eq!(start, result);
172+
assert_eq!(len, expected_len);
168173
}
169-
test_encode_decode(StructWithSerde {
170-
serde: SerdeType { a: 5 },
171-
});
172-
test_encode_decode(EnumWithSerde::Unit(SerdeType { a: 5 }));
173-
test_encode_decode(EnumWithSerde::Struct {
174-
serde: SerdeType { a: 5 },
175-
});
174+
test_encode_decode(
175+
StructWithSerde {
176+
serde: SerdeType { a: 5 },
177+
},
178+
1,
179+
);
180+
test_encode_decode(EnumWithSerde::Unit(SerdeType { a: 5 }), 2);
181+
test_encode_decode(
182+
EnumWithSerde::Struct {
183+
serde: SerdeType { a: 5 },
184+
},
185+
2,
186+
);
176187
}
177188
}

tests/std.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,16 @@ fn test_std_commons() {
106106
// &CStr
107107
let cstr = CStr::from_bytes_with_nul(b"Hello world\0").unwrap();
108108
let len = bincode::encode_into_slice(cstr, &mut buffer, config).unwrap();
109-
let decoded: &CStr = bincode::decode_from_slice(&mut buffer[..len], config).unwrap();
109+
let (decoded, len): (&CStr, usize) =
110+
bincode::decode_from_slice(&mut buffer[..len], config).unwrap();
110111
assert_eq!(cstr, decoded);
112+
assert_eq!(len, 13);
111113

112114
// Path
113115
let path = Path::new("C:/Program Files/Foo");
114116
let len = bincode::encode_into_slice(path, &mut buffer, config).unwrap();
115-
let decoded: &Path = bincode::decode_from_slice(&mut buffer[..len], config).unwrap();
117+
let (decoded, len): (&Path, usize) =
118+
bincode::decode_from_slice(&mut buffer[..len], config).unwrap();
116119
assert_eq!(path, decoded);
120+
assert_eq!(len, 21);
117121
}

tests/utils.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ where
1515
&buffer[..len],
1616
core::any::type_name::<C>()
1717
);
18-
let decoded: V = bincode::decode_from_slice(&mut buffer, config).unwrap();
18+
let (decoded, decoded_len): (V, usize) =
19+
bincode::decode_from_slice(&mut buffer, config).unwrap();
1920

2021
assert!(
2122
cmp(&element, &decoded),
@@ -24,6 +25,7 @@ where
2425
element,
2526
&buffer[..len],
2627
);
28+
assert_eq!(len, decoded_len);
2729
}
2830

2931
pub fn the_same_with_comparer<V, CMP>(element: V, cmp: CMP)

0 commit comments

Comments
 (0)