Skip to content

Commit dd9dcc9

Browse files
bors[bot]dflemstr
andauthored
23: Attempt to add support for de/serializing maps r=japaric a=dflemstr This enables constructing map-like types (a PR for that to heapless will follow) Co-authored-by: David Flemström <dflemstr@spotify.com>
2 parents 0b808de + 0f2ee31 commit dd9dcc9

File tree

4 files changed

+84
-27
lines changed

4 files changed

+84
-27
lines changed

src/de/mod.rs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -527,22 +527,7 @@ impl<'a, 'de> de::Deserializer<'de> for &'a mut Deserializer<'de> {
527527
self.deserialize_seq(visitor)
528528
}
529529

530-
/// Unsupported. Can’t make an arbitrary-sized map in no-std. Use a struct with a
531-
/// known format, or implement a custom map deserializer / visitor:
532-
/// https://serde.rs/deserialize-map.html
533-
fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value>
534-
where
535-
V: Visitor<'de>,
536-
{
537-
unreachable!()
538-
}
539-
540-
fn deserialize_struct<V>(
541-
self,
542-
_name: &'static str,
543-
_fields: &'static [&'static str],
544-
visitor: V,
545-
) -> Result<V::Value>
530+
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
546531
where
547532
V: Visitor<'de>,
548533
{
@@ -561,6 +546,18 @@ impl<'a, 'de> de::Deserializer<'de> for &'a mut Deserializer<'de> {
561546
}
562547
}
563548

549+
fn deserialize_struct<V>(
550+
self,
551+
_name: &'static str,
552+
_fields: &'static [&'static str],
553+
visitor: V,
554+
) -> Result<V::Value>
555+
where
556+
V: Visitor<'de>,
557+
{
558+
self.deserialize_map(visitor)
559+
}
560+
564561
fn deserialize_enum<V>(
565562
self,
566563
_name: &'static str,

src/ser/map.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
use serde::ser;
2+
3+
use heapless::ArrayLength;
4+
5+
use crate::ser::{Error, Result, Serializer};
6+
7+
pub struct SerializeMap<'a, B>
8+
where
9+
B: ArrayLength<u8>,
10+
{
11+
ser: &'a mut Serializer<B>,
12+
first: bool,
13+
}
14+
15+
impl<'a, B> SerializeMap<'a, B>
16+
where
17+
B: ArrayLength<u8>,
18+
{
19+
pub(crate) fn new(ser: &'a mut Serializer<B>) -> Self {
20+
SerializeMap { ser, first: true }
21+
}
22+
}
23+
24+
impl<'a, B> ser::SerializeMap for SerializeMap<'a, B>
25+
where
26+
B: ArrayLength<u8>,
27+
{
28+
type Ok = ();
29+
type Error = Error;
30+
31+
fn end(self) -> Result<Self::Ok> {
32+
self.ser.buf.push(b'}')?;
33+
Ok(())
34+
}
35+
36+
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()>
37+
where
38+
T: ser::Serialize,
39+
{
40+
if !self.first {
41+
self.ser.buf.push(b',')?;
42+
}
43+
self.first = false;
44+
key.serialize(&mut *self.ser)?;
45+
self.ser.buf.extend_from_slice(b":")?;
46+
Ok(())
47+
}
48+
49+
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()>
50+
where
51+
T: ser::Serialize,
52+
{
53+
value.serialize(&mut *self.ser)?;
54+
Ok(())
55+
}
56+
}

src/ser/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ use serde::ser;
66

77
use heapless::{consts::*, String, Vec};
88

9+
use self::map::SerializeMap;
910
use self::seq::SerializeSeq;
1011
use self::struct_::SerializeStruct;
1112

13+
mod map;
1214
mod seq;
1315
mod struct_;
1416

@@ -142,7 +144,7 @@ where
142144
type SerializeTuple = SerializeSeq<'a, B>;
143145
type SerializeTupleStruct = Unreachable;
144146
type SerializeTupleVariant = Unreachable;
145-
type SerializeMap = Unreachable;
147+
type SerializeMap = SerializeMap<'a, B>;
146148
type SerializeStruct = SerializeStruct<'a, B>;
147149
type SerializeStructVariant = Unreachable;
148150

@@ -301,7 +303,9 @@ where
301303
}
302304

303305
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
304-
unreachable!()
306+
self.buf.push(b'{')?;
307+
308+
Ok(SerializeMap::new(self))
305309
}
306310

307311
fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {

src/ser/struct_.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ pub struct SerializeStruct<'a, B>
88
where
99
B: ArrayLength<u8>,
1010
{
11-
de: &'a mut Serializer<B>,
11+
ser: &'a mut Serializer<B>,
1212
first: bool,
1313
}
1414

1515
impl<'a, B> SerializeStruct<'a, B>
1616
where
1717
B: ArrayLength<u8>,
1818
{
19-
pub(crate) fn new(de: &'a mut Serializer<B>) -> Self {
20-
SerializeStruct { de, first: true }
19+
pub(crate) fn new(ser: &'a mut Serializer<B>) -> Self {
20+
SerializeStruct { ser, first: true }
2121
}
2222
}
2323

@@ -34,21 +34,21 @@ where
3434
{
3535
// XXX if `value` is `None` we not produce any output for this field
3636
if !self.first {
37-
self.de.buf.push(b',')?;
37+
self.ser.buf.push(b',')?;
3838
}
3939
self.first = false;
4040

41-
self.de.buf.push(b'"')?;
42-
self.de.buf.extend_from_slice(key.as_bytes())?;
43-
self.de.buf.extend_from_slice(b"\":")?;
41+
self.ser.buf.push(b'"')?;
42+
self.ser.buf.extend_from_slice(key.as_bytes())?;
43+
self.ser.buf.extend_from_slice(b"\":")?;
4444

45-
value.serialize(&mut *self.de)?;
45+
value.serialize(&mut *self.ser)?;
4646

4747
Ok(())
4848
}
4949

5050
fn end(self) -> Result<Self::Ok> {
51-
self.de.buf.push(b'}')?;
51+
self.ser.buf.push(b'}')?;
5252
Ok(())
5353
}
5454
}

0 commit comments

Comments
 (0)