Skip to content

Commit faf45dd

Browse files
committed
Merge pull request #44 from 3Hren/pr/fix-serde-enums
Several serde deserialization fixes
2 parents d5891ce + 43f3ac3 commit faf45dd

9 files changed

Lines changed: 620 additions & 294 deletions

File tree

CHANGELOG.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ All notable changes to this project will be documented in this file.
33
This project adheres to [Semantic Versioning](http://semver.org/).
44

55
## [Unreleased][unreleased]
6-
### Added
7-
- Serde serializer can now be extended with custom struct encoding policy.
86

97
## 0.7.0 - 2015-08-24
108
### Changed

rmp-serde/CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Change Log
2+
All notable changes to this project will be documented in this file.
3+
This project adheres to [Semantic Versioning](http://semver.org/).
4+
5+
## [Unreleased][unreleased]
6+
### Changed
7+
- Serializer can now be extended with custom struct encoding policy.
8+
- Improved error types and its messages for serialization part.
9+
- New error type introduced - UnknownLength. Returned on attempt to serialize struct, map or serquence with unknown
10+
length (Serde allows this).
11+
- The new type is returned if necessary.
12+
13+
### Fixed
14+
- Deserializer now properly works with enums.
15+
- Options with default values (that can be initialized using unit marker) deserialization.
16+
This fix also forbids the following Option deserialization cases:
17+
- Option<()>.
18+
- Option<Option<...>>.
19+
It's impossible to properly deserialize the listed cases without explicit option marker in protocol.
20+
- Serializer now properly serializes unit structs.
21+
Previously it was serialized as a unit (nil), now there is just an empty array ([]).

rmp-serde/src/decode.rs

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rmp::decode::{
1212
MarkerReadError,
1313
ReadError,
1414
ValueReadError,
15+
read_array_size,
1516
read_numeric_data,
1617
read_str_data,
1718
read_marker,
@@ -75,7 +76,7 @@ impl serde::de::Error for Error {
7576
serde::de::Type::Str => Error::TypeMismatch(Marker::Str32),
7677
serde::de::Type::String => Error::TypeMismatch(Marker::Str32),
7778
serde::de::Type::Unit => Error::TypeMismatch(Marker::Null),
78-
serde::de::Type::Option => Error::TypeMismatch(Marker::True),
79+
serde::de::Type::Option => Error::TypeMismatch(Marker::Null),
7980
serde::de::Type::Seq => Error::TypeMismatch(Marker::Array32),
8081
serde::de::Type::Map => Error::TypeMismatch(Marker::Map32),
8182
serde::de::Type::UnitStruct => Error::TypeMismatch(Marker::Null),
@@ -150,6 +151,15 @@ impl From<MarkerReadError> for Error {
150151
}
151152
}
152153

154+
impl From<serde::de::value::Error> for Error {
155+
fn from(err: serde::de::value::Error) -> Error {
156+
match err {
157+
serde::de::value::Error::SyntaxError => Error::Syntax("unknown".into()),
158+
_ => Error::Uncategorized("unknown".into()),
159+
}
160+
}
161+
}
162+
153163
pub type Result<T> = result::Result<T, Error>;
154164

155165
/// # Note
@@ -160,6 +170,7 @@ pub type Result<T> = result::Result<T, Error>;
160170
pub struct Deserializer<R: Read> {
161171
rd: R,
162172
buf: Vec<u8>,
173+
decoding_option: bool,
163174
}
164175

165176
impl<R: Read> Deserializer<R> {
@@ -168,6 +179,7 @@ impl<R: Read> Deserializer<R> {
168179
Deserializer {
169180
rd: rd,
170181
buf: Vec::new(),
182+
decoding_option: false,
171183
}
172184
}
173185

@@ -237,8 +249,16 @@ impl<R: Read> serde::Deserializer for Deserializer<R> {
237249
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value>
238250
where V: serde::de::Visitor
239251
{
240-
match try!(read_marker(&mut self.rd)) {
241-
Marker::Null => visitor.visit_unit(),
252+
let marker = try!(read_marker(&mut self.rd));
253+
254+
match marker {
255+
Marker::Null => {
256+
if self.decoding_option {
257+
visitor.visit_none()
258+
} else {
259+
visitor.visit_unit()
260+
}
261+
}
242262
Marker::True => visitor.visit_bool(true),
243263
Marker::False => visitor.visit_bool(false),
244264
Marker::FixPos(val) => visitor.visit_u8(val),
@@ -307,14 +327,37 @@ impl<R: Read> serde::Deserializer for Deserializer<R> {
307327
}
308328

309329
/// We treat Value::Null as None.
330+
///
331+
/// # Note
332+
///
333+
/// Without using explicit option marker it's impossible to properly deserialize the following
334+
/// specific cases:
335+
/// - `Option<()>`.
336+
/// - nested optionals, like `Option<Option<...>>`.
310337
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value>
311338
where V: serde::de::Visitor,
312339
{
313340
// Primarily try to read optimisticly.
314-
match visitor.visit_some(self) {
341+
self.decoding_option = true;
342+
let res = match visitor.visit_some(self) {
315343
Ok(val) => Ok(val),
316344
Err(Error::TypeMismatch(Marker::Null)) => visitor.visit_none(),
317345
Err(err) => Err(err)
346+
};
347+
self.decoding_option = false;
348+
349+
res
350+
}
351+
352+
fn visit_enum<V>(&mut self, _enum: &str, _variants: &'static [&'static str], mut visitor: V)
353+
-> Result<V::Value>
354+
where V: serde::de::EnumVisitor
355+
{
356+
let len = try!(read_array_size(&mut self.rd));
357+
358+
match len {
359+
2 => visitor.visit(VariantVisitor::new(self)),
360+
n => Err(Error::LengthMismatch(n as u32)),
318361
}
319362
}
320363
}
@@ -385,3 +428,55 @@ impl<'a, R: Read + 'a> serde::de::MapVisitor for MapVisitor<'a, R> {
385428
}
386429
}
387430
}
431+
432+
/// Default variant visitor.
433+
///
434+
/// # Note
435+
///
436+
/// We use default behaviour for new type, which decodes enums with a single value as a tuple.
437+
pub struct VariantVisitor<'a, R: Read + 'a> {
438+
de: &'a mut Deserializer<R>,
439+
}
440+
441+
impl<'a, R: Read + 'a> VariantVisitor<'a, R> {
442+
pub fn new(de: &'a mut Deserializer<R>) -> VariantVisitor<'a, R> {
443+
VariantVisitor {
444+
de: de,
445+
}
446+
}
447+
}
448+
449+
impl<'a, R: Read> serde::de::VariantVisitor for VariantVisitor<'a, R> {
450+
type Error = Error;
451+
452+
// Resolves an internal variant type by integer id.
453+
fn visit_variant<V>(&mut self) -> Result<V>
454+
where V: serde::Deserialize
455+
{
456+
use serde::de::value::ValueDeserializer;
457+
458+
let id: u32 = try!(serde::Deserialize::deserialize(self.de));
459+
460+
let mut de = (id as usize).into_deserializer();
461+
Ok(try!(V::deserialize(&mut de)))
462+
}
463+
464+
fn visit_unit(&mut self) -> Result<()> {
465+
use serde::de::Deserialize;
466+
467+
type T = ();
468+
T::deserialize(self.de)
469+
}
470+
471+
fn visit_tuple<V>(&mut self, len: usize, visitor: V) -> Result<V::Value>
472+
where V: serde::de::Visitor,
473+
{
474+
serde::de::Deserializer::visit_tuple(self.de, len, visitor)
475+
}
476+
477+
fn visit_struct<V>(&mut self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
478+
where V: serde::de::Visitor,
479+
{
480+
serde::de::Deserializer::visit_tuple(self.de, fields.len(), visitor)
481+
}
482+
}

rmp-serde/src/encode.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,25 @@ pub enum Error {
2525
/// Failed to write MessagePack'ed single-byte value into the write.
2626
InvalidFixedValueWrite(WriteError),
2727
InvalidValueWrite(ValueWriteError),
28+
29+
/// Failed to serialize struct, sequence or map, because its length is unknown.
30+
UnknownLength,
2831
}
2932

3033
impl ::std::error::Error for Error {
31-
fn description(&self) -> &str { "an error occurred while writing encoded value" }
34+
fn description(&self) -> &str {
35+
match *self {
36+
Error::InvalidFixedValueWrite(..) => "invalid fixed value write",
37+
Error::InvalidValueWrite(..) => "invalid value write",
38+
Error::UnknownLength => "attempt to serialize struct, sequence or map with unknown length",
39+
}
40+
}
3241

3342
fn cause(&self) -> Option<&::std::error::Error> {
3443
match *self {
3544
Error::InvalidFixedValueWrite(ref err) => Some(err),
3645
Error::InvalidValueWrite(ref err) => Some(err),
46+
Error::UnknownLength => None,
3747
}
3848
}
3949
}
@@ -229,7 +239,7 @@ impl<'a, W: VariantWriter> serde::Serializer for Serializer<'a, W> {
229239

230240
let len = match visitor.len() {
231241
Some(len) => len,
232-
None => panic!("do not know how to serialize a sequence with no length"),
242+
None => return Err(Error::UnknownLength),
233243
};
234244

235245
// ... and its arguments length.
@@ -266,7 +276,7 @@ impl<'a, W: VariantWriter> serde::Serializer for Serializer<'a, W> {
266276
{
267277
let len = match visitor.len() {
268278
Some(len) => len,
269-
None => panic!("do not know how to serialize a sequence with no length"),
279+
None => return Err(Error::UnknownLength),
270280
};
271281

272282
try!(write_array_len(&mut self.wr, len as u32));
@@ -287,7 +297,7 @@ impl<'a, W: VariantWriter> serde::Serializer for Serializer<'a, W> {
287297
{
288298
let len = match visitor.len() {
289299
Some(len) => len,
290-
None => panic!("do not know how to serialize a map with no length"),
300+
None => return Err(Error::UnknownLength),
291301
};
292302

293303
try!(write_map_len(&mut self.wr, len as u32));
@@ -305,12 +315,18 @@ impl<'a, W: VariantWriter> serde::Serializer for Serializer<'a, W> {
305315
value.serialize(self)
306316
}
307317

318+
fn visit_unit_struct(&mut self, _name: &'static str) -> Result<(), Error> {
319+
try!(write_array_len(&mut self.wr, 0));
320+
321+
Ok(())
322+
}
323+
308324
fn visit_struct<V>(&mut self, _name: &str, mut visitor: V) -> Result<(), Error>
309325
where V: serde::ser::MapVisitor,
310326
{
311327
let len = match visitor.len() {
312328
Some(len) => len,
313-
None => panic!("do not know how to serialize a sequence with no length"),
329+
None => return Err(Error::UnknownLength),
314330
};
315331

316332
try!(self.vw.write_struct_len(&mut self.wr, len as u32));

0 commit comments

Comments
 (0)