diff --git a/src/de.rs b/src/de.rs index 170e0593..33a6e713 100644 --- a/src/de.rs +++ b/src/de.rs @@ -54,6 +54,42 @@ where Ok(value) } +/// Decodes a value from the first piece of valid CBOR data in a slice, +/// returning the number of bytes read to produce the value. +/// +/// # Examples +/// +/// Deserialize a `String` +/// +/// ``` +/// # use serde_cbor::de; +/// let v: Vec = vec![0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, +/// 0xde, 0xad, 0xbe, 0xef]; // nonsense trailing data +/// let (value, len): (String, _) = de::from_slice_count(&v[..]).unwrap(); +/// assert_eq!(value, "foobar"); +/// assert_eq!(len, 7); +/// ``` +/// +/// Deserialize two consecutive `String`s +/// +/// ``` +/// # use serde_cbor::de; +/// let v: Vec = vec![0x63, 0x66, 0x6F, 0x6F, 0x63, 0x62, 0x61, 0x72]; +/// let (value_1, off): (String, _) = de::from_slice_count(&v[..]).unwrap(); +/// let (value_2, _): (String, _) = de::from_slice_count(&v[off..]).unwrap(); +/// assert_eq!(value_1, "foo"); +/// assert_eq!(value_2, "bar"); +/// ``` +#[cfg(any(feature = "std", feature = "alloc"))] +pub fn from_slice_count<'a, T>(slice: &'a [u8]) -> Result<(T, usize)> +where + T: de::Deserialize<'a>, +{ + let mut deserializer = Deserializer::from_slice(slice); + let value = de::Deserialize::deserialize(&mut deserializer)?; + Ok((value, deserializer.byte_offset())) +} + // When the "std" feature is enabled there should be little to no need to ever use this function, // as `from_slice` covers all use cases (at the expense of being less efficient). /// Decode a value from CBOR data in a mutable slice.