Skip to content

Commit 8f8e811

Browse files
committed
Support serde_spanned::Spanned<T> deserialization
1 parent fc47aec commit 8f8e811

4 files changed

Lines changed: 370 additions & 60 deletions

File tree

source/postcard/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ rustdoc-args = ["--cfg", "docsrs"]
2424

2525
[dependencies]
2626

27+
[dependencies.serde_spanned]
28+
version = "0.6.8"
29+
features = ["serde"]
30+
optional = true
31+
2732
[dependencies.heapless]
2833
version = "0.7.0"
2934
default-features = false
@@ -86,6 +91,7 @@ use-crc = ["crc"]
8691

8792
# Does nothing, for compat only
8893
paste = []
94+
serde_spanned = ["dep:serde_spanned"]
8995

9096
# Experimental features!
9197
#

source/postcard/src/de/deserializer.rs

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ use core::marker::PhantomData;
1212
pub struct Deserializer<'de, F: Flavor<'de>> {
1313
flavor: F,
1414
_plt: PhantomData<&'de ()>,
15+
16+
#[cfg(feature = "serde_spanned")]
17+
pub(crate) pos: usize,
1518
}
1619

1720
impl<'de, F> Deserializer<'de, F>
@@ -23,6 +26,8 @@ where
2326
Deserializer {
2427
flavor,
2528
_plt: PhantomData,
29+
#[cfg(feature = "serde_spanned")]
30+
pos: 0,
2631
}
2732
}
2833

@@ -39,11 +44,43 @@ impl<'de> Deserializer<'de, Slice<'de>> {
3944
Deserializer {
4045
flavor: Slice::new(input),
4146
_plt: PhantomData,
47+
#[cfg(feature = "serde_spanned")]
48+
pos: 0,
4249
}
4350
}
4451
}
4552

4653
impl<'de, F: Flavor<'de>> Deserializer<'de, F> {
54+
#[inline]
55+
fn next_byte(&mut self) -> Result<u8> {
56+
let byte = self.flavor.pop()?;
57+
#[cfg(feature = "serde_spanned")]
58+
{
59+
self.pos += 1;
60+
}
61+
Ok(byte)
62+
}
63+
64+
#[inline]
65+
fn next_n_bytes(&mut self, ct: usize) -> Result<&'de [u8]> {
66+
let slice = self.flavor.try_take_n(ct)?;
67+
#[cfg(feature = "serde_spanned")]
68+
{
69+
self.pos += ct;
70+
}
71+
Ok(slice)
72+
}
73+
74+
#[inline]
75+
fn next_n_bytes_temp(&mut self, ct: usize) -> Result<&[u8]> {
76+
let slice = self.flavor.try_take_n_temp(ct)?;
77+
#[cfg(feature = "serde_spanned")]
78+
{
79+
self.pos += ct;
80+
}
81+
Ok(slice)
82+
}
83+
4784
#[cfg(target_pointer_width = "16")]
4885
#[inline(always)]
4986
fn try_take_varint_usize(&mut self) -> Result<usize> {
@@ -66,7 +103,7 @@ impl<'de, F: Flavor<'de>> Deserializer<'de, F> {
66103
fn try_take_varint_u16(&mut self) -> Result<u16> {
67104
let mut out = 0;
68105
for i in 0..varint_max::<u16>() {
69-
let val = self.flavor.pop()?;
106+
let val = self.next_byte()?;
70107
let carry = (val & 0x7F) as u16;
71108
out |= carry << (7 * i);
72109

@@ -85,7 +122,7 @@ impl<'de, F: Flavor<'de>> Deserializer<'de, F> {
85122
fn try_take_varint_u32(&mut self) -> Result<u32> {
86123
let mut out = 0;
87124
for i in 0..varint_max::<u32>() {
88-
let val = self.flavor.pop()?;
125+
let val = self.next_byte()?;
89126
let carry = (val & 0x7F) as u32;
90127
out |= carry << (7 * i);
91128

@@ -104,7 +141,7 @@ impl<'de, F: Flavor<'de>> Deserializer<'de, F> {
104141
fn try_take_varint_u64(&mut self) -> Result<u64> {
105142
let mut out = 0;
106143
for i in 0..varint_max::<u64>() {
107-
let val = self.flavor.pop()?;
144+
let val = self.next_byte()?;
108145
let carry = (val & 0x7F) as u64;
109146
out |= carry << (7 * i);
110147

@@ -123,7 +160,7 @@ impl<'de, F: Flavor<'de>> Deserializer<'de, F> {
123160
fn try_take_varint_u128(&mut self) -> Result<u128> {
124161
let mut out = 0;
125162
for i in 0..varint_max::<u128>() {
126-
let val = self.flavor.pop()?;
163+
let val = self.next_byte()?;
127164
let carry = (val & 0x7F) as u128;
128165
out |= carry << (7 * i);
129166

@@ -201,6 +238,14 @@ impl<'a, 'b: 'a, F: Flavor<'b>> serde::de::MapAccess<'b> for MapAccess<'a, 'b, F
201238
}
202239
}
203240

241+
impl<'de, F: Flavor<'de>> de::IntoDeserializer<'de, Error> for &mut Deserializer<'de, F> {
242+
type Deserializer = Self;
243+
244+
fn into_deserializer(self) -> Self::Deserializer {
245+
self
246+
}
247+
}
248+
204249
impl<'de, F: Flavor<'de>> de::Deserializer<'de> for &mut Deserializer<'de, F> {
205250
type Error = Error;
206251

@@ -225,7 +270,7 @@ impl<'de, F: Flavor<'de>> de::Deserializer<'de> for &mut Deserializer<'de, F> {
225270
where
226271
V: Visitor<'de>,
227272
{
228-
let val = match self.flavor.pop()? {
273+
let val = match self.next_byte()? {
229274
0 => false,
230275
1 => true,
231276
_ => return Err(Error::DeserializeBadBool),
@@ -238,7 +283,7 @@ impl<'de, F: Flavor<'de>> de::Deserializer<'de> for &mut Deserializer<'de, F> {
238283
where
239284
V: Visitor<'de>,
240285
{
241-
visitor.visit_i8(self.flavor.pop()? as i8)
286+
visitor.visit_i8(self.next_byte()? as i8)
242287
}
243288

244289
#[inline]
@@ -282,7 +327,7 @@ impl<'de, F: Flavor<'de>> de::Deserializer<'de> for &mut Deserializer<'de, F> {
282327
where
283328
V: Visitor<'de>,
284329
{
285-
visitor.visit_u8(self.flavor.pop()?)
330+
visitor.visit_u8(self.next_byte()?)
286331
}
287332

288333
#[inline]
@@ -326,7 +371,7 @@ impl<'de, F: Flavor<'de>> de::Deserializer<'de> for &mut Deserializer<'de, F> {
326371
where
327372
V: Visitor<'de>,
328373
{
329-
let bytes = self.flavor.try_take_n_temp(4)?;
374+
let bytes = self.next_n_bytes_temp(4)?;
330375
let mut buf = [0u8; 4];
331376
buf.copy_from_slice(bytes);
332377
visitor.visit_f32(f32::from_bits(u32::from_le_bytes(buf)))
@@ -337,7 +382,7 @@ impl<'de, F: Flavor<'de>> de::Deserializer<'de> for &mut Deserializer<'de, F> {
337382
where
338383
V: Visitor<'de>,
339384
{
340-
let bytes = self.flavor.try_take_n_temp(8)?;
385+
let bytes = self.next_n_bytes_temp(8)?;
341386
let mut buf = [0u8; 8];
342387
buf.copy_from_slice(bytes);
343388
visitor.visit_f64(f64::from_bits(u64::from_le_bytes(buf)))
@@ -352,7 +397,7 @@ impl<'de, F: Flavor<'de>> de::Deserializer<'de> for &mut Deserializer<'de, F> {
352397
if sz > 4 {
353398
return Err(Error::DeserializeBadChar);
354399
}
355-
let bytes: &[u8] = self.flavor.try_take_n_temp(sz)?;
400+
let bytes: &[u8] = self.next_n_bytes_temp(sz)?;
356401
// we pass the character through string conversion because
357402
// this handles transforming the array of code units to a
358403
// codepoint. we can't use char::from_u32() because it expects
@@ -371,7 +416,7 @@ impl<'de, F: Flavor<'de>> de::Deserializer<'de> for &mut Deserializer<'de, F> {
371416
V: Visitor<'de>,
372417
{
373418
let sz = self.try_take_varint_usize()?;
374-
let bytes: &'de [u8] = self.flavor.try_take_n(sz)?;
419+
let bytes: &'de [u8] = self.next_n_bytes(sz)?;
375420
let str_sl = core::str::from_utf8(bytes).map_err(|_| Error::DeserializeBadUtf8)?;
376421

377422
visitor.visit_borrowed_str(str_sl)
@@ -395,7 +440,7 @@ impl<'de, F: Flavor<'de>> de::Deserializer<'de> for &mut Deserializer<'de, F> {
395440
V: Visitor<'de>,
396441
{
397442
let sz = self.try_take_varint_usize()?;
398-
let bytes: &'de [u8] = self.flavor.try_take_n(sz)?;
443+
let bytes: &'de [u8] = self.next_n_bytes(sz)?;
399444
visitor.visit_borrowed_bytes(bytes)
400445
}
401446

@@ -414,7 +459,7 @@ impl<'de, F: Flavor<'de>> de::Deserializer<'de> for &mut Deserializer<'de, F> {
414459
where
415460
V: Visitor<'de>,
416461
{
417-
match self.flavor.pop()? {
462+
match self.next_byte()? {
418463
0 => visitor.visit_none(),
419464
1 => visitor.visit_some(self),
420465
_ => Err(Error::DeserializeBadOption),
@@ -502,13 +547,19 @@ impl<'de, F: Flavor<'de>> de::Deserializer<'de> for &mut Deserializer<'de, F> {
502547
#[inline]
503548
fn deserialize_struct<V>(
504549
self,
505-
_name: &'static str,
550+
name: &'static str,
506551
fields: &'static [&'static str],
507552
visitor: V,
508553
) -> Result<V::Value>
509554
where
510555
V: Visitor<'de>,
511556
{
557+
let _ = name;
558+
559+
#[cfg(feature = "serde_spanned")]
560+
if serde_spanned::__unstable::is_spanned(name, fields) {
561+
return visitor.visit_map(crate::de::spanned::SpannedDeserializer::new(self));
562+
}
512563
self.deserialize_tuple(fields.len(), visitor)
513564
}
514565

0 commit comments

Comments
 (0)