@@ -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+
153163pub type Result < T > = result:: Result < T , Error > ;
154164
155165/// # Note
@@ -160,6 +170,7 @@ pub type Result<T> = result::Result<T, Error>;
160170pub struct Deserializer < R : Read > {
161171 rd : R ,
162172 buf : Vec < u8 > ,
173+ decoding_option : bool ,
163174}
164175
165176impl < 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+ }
0 commit comments