Skip to content

Commit 87ca3f3

Browse files
committed
Preliminary support for encoding structs as maps
1 parent 0e69c67 commit 87ca3f3

3 files changed

Lines changed: 78 additions & 1 deletion

File tree

rmp-serde/src/encode.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,24 @@ impl From<ValueWriteError> for Error {
7272
// TODO: Docs. Examples.
7373
pub struct Serializer<'a> {
7474
wr: &'a mut Write,
75+
verbose: bool,
7576
}
7677

7778
impl<'a> Serializer<'a> {
7879
/// Creates a new MessagePack encoder whose output will be written to the writer specified.
7980
pub fn new(wr: &'a mut Write) -> Serializer<'a> {
8081
Serializer {
8182
wr: wr,
83+
verbose: false,
84+
}
85+
}
86+
87+
/// Creates a new MessagePack encoder whose output will be written to the writer specified.
88+
/// structs will be written as maps in MessagePack
89+
pub fn new_verbose(wr: &'a mut Write) -> Serializer<'a> {
90+
Serializer {
91+
wr: wr,
92+
verbose: true,
8293
}
8394
}
8495
}
@@ -276,7 +287,11 @@ impl<'a> serde::Serializer for Serializer<'a> {
276287
None => panic!("do not know how to serialize a sequence with no length"),
277288
};
278289

279-
try!(write_array_len(&mut self.wr, len as u32));
290+
if self.verbose {
291+
try!(write_map_len(&mut self.wr, len as u32));
292+
} else {
293+
try!(write_array_len(&mut self.wr, len as u32));
294+
}
280295

281296
while let Some(()) = try!(visitor.visit(self)) { }
282297

@@ -286,6 +301,11 @@ impl<'a> serde::Serializer for Serializer<'a> {
286301
fn visit_struct_elt<V>(&mut self, _key: &str, value: V) -> Result<(), Error>
287302
where V: serde::Serialize,
288303
{
304+
if self.verbose {
305+
if let Err(e) = write_str(&mut self.wr, _key).map_err(From::from) {
306+
return Err(e);
307+
}
308+
}
289309
value.serialize(self)
290310
}
291311

rmp-serde/tests/deserializer.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,36 @@ fn pass_map() {
340340
assert_eq!(expected, actual);
341341
}
342342

343+
#[cfg(feature = "serde_macros")]
344+
#[test]
345+
fn pass_struct_map() {
346+
#[derive(Debug, PartialEq, Deserialize)]
347+
struct Custom {
348+
et: String,
349+
le: u8,
350+
shit: u8,
351+
}
352+
353+
let buf = [
354+
0x83, // 3 (size)
355+
0xa2, 0x65, 0x74, // "et"
356+
0xa5, 0x76, 0x6f, 0x69, 0x6c, 0x61, // "voila"
357+
0xa2, 0x6c, 0x65, // "le"
358+
0x00, // 0
359+
0xa4, 0x73, 0x68, 0x69, 0x74, // "shit"
360+
0x01, // 1
361+
];
362+
let cur = Cursor::new(&buf[..]);
363+
364+
// it appears no special behavior is needed for deserializing structs encoded as maps
365+
let mut deserializer = Deserializer::new(cur);
366+
let actual: Custom = Deserialize::deserialize(&mut deserializer).unwrap();
367+
let voila = "voila".to_string(); // so the next line looks more funny
368+
let expected = Custom { et: voila, le: 0, shit: 1 };
369+
370+
assert_eq!(expected, actual);
371+
}
372+
343373
#[cfg(feature = "serde_macros")]
344374
#[test]
345375
fn pass_enum() {

rmp-serde/tests/serializer.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,33 @@ fn pass_map() {
267267
assert_eq!(out, buf);
268268
}
269269

270+
#[cfg(feature = "serde_macros")]
271+
#[test]
272+
fn pass_struct_map() {
273+
#[derive(Debug, PartialEq, Serialize)]
274+
struct Custom<'a> {
275+
et: &'a str,
276+
le: u8,
277+
shit: u8,
278+
}
279+
280+
let mut buf = [0x00; 20];
281+
282+
let val = Custom { et: "voila", le: 0, shit: 1 };
283+
val.serialize(&mut Serializer::new_verbose(&mut &mut buf[..])).ok().unwrap();
284+
285+
let out = [
286+
0x83, // 3 (size)
287+
0xa2, 0x65, 0x74, // "et"
288+
0xa5, 0x76, 0x6f, 0x69, 0x6c, 0x61, // "voila"
289+
0xa2, 0x6c, 0x65, // "le"
290+
0x00, // 0
291+
0xa4, 0x73, 0x68, 0x69, 0x74, // "shit"
292+
0x01, // 1
293+
];
294+
assert_eq!(out, buf);
295+
}
296+
270297
#[cfg(feature = "serde_macros")]
271298
#[test]
272299
fn pass_enum() {

0 commit comments

Comments
 (0)