@@ -35,6 +35,9 @@ impl DeriveEnum {
3535 fn_body. ident_str ( "match" ) ;
3636 fn_body. ident_str ( "self" ) ;
3737 fn_body. group ( Delimiter :: Brace , |match_body| {
38+ if self . variants . is_empty ( ) {
39+ self . encode_empty_enum_case ( match_body) ?;
40+ }
3841 for ( variant_index, variant) in self . iter_fields ( ) {
3942 // Self::Variant
4043 match_body. ident_str ( "Self" ) ;
@@ -101,18 +104,24 @@ impl DeriveEnum {
101104 ?;
102105 }
103106 }
107+ body. push_parsed ( "Ok(())" ) ?;
104108 Ok ( ( ) )
105109 } ) ?;
106110 match_body. punct ( ',' ) ;
107111 }
108112 Ok ( ( ) )
109113 } ) ?;
110- fn_body. push_parsed ( "Ok(())" ) ?;
111114 Ok ( ( ) )
112115 } ) ?;
113116 Ok ( ( ) )
114117 }
115118
119+ /// If we're encoding an empty enum, we need to add an empty case in the form of:
120+ /// `_ => core::unreachable!(),`
121+ fn encode_empty_enum_case ( & self , builder : & mut StreamBuilder ) -> Result {
122+ builder. push_parsed ( "_ => core::unreachable!()" ) . map ( |_| ( ) )
123+ }
124+
116125 /// Build the catch-all case for an int-to-enum decode implementation
117126 fn invalid_variant_case ( & self , enum_name : & str , result : & mut StreamBuilder ) -> Result {
118127 // we'll be generating:
@@ -195,57 +204,61 @@ impl DeriveEnum {
195204 . with_arg ( "mut decoder" , "D" )
196205 . with_return_type ( "core::result::Result<Self, bincode::error::DecodeError>" )
197206 . body ( |fn_builder| {
198- fn_builder
199- . push_parsed (
200- "let variant_index = <u32 as bincode::Decode>::decode(&mut decoder)?;" ,
201- ) ?;
202- fn_builder. push_parsed ( "match variant_index" ) ?;
203- fn_builder. group ( Delimiter :: Brace , |variant_case| {
204- for ( mut variant_index, variant) in self . iter_fields ( ) {
205- // idx => Ok(..)
206- if variant_index. len ( ) > 1 {
207- variant_case. push_parsed ( "x if x == " ) ?;
208- variant_case. extend ( variant_index) ;
209- } else {
210- variant_case. push ( variant_index. remove ( 0 ) ) ;
211- }
212- variant_case. puncts ( "=>" ) ;
213- variant_case. ident_str ( "Ok" ) ;
214- variant_case. group ( Delimiter :: Parenthesis , |variant_case_body| {
215- // Self::Variant { }
216- // Self::Variant { 0: ..., 1: ... 2: ... },
217- // Self::Variant { a: ..., b: ... c: ... },
218- variant_case_body. ident_str ( "Self" ) ;
219- variant_case_body. puncts ( "::" ) ;
220- variant_case_body. ident ( variant. name . clone ( ) ) ;
207+ if self . variants . is_empty ( ) {
208+ fn_builder. push_parsed ( "core::result::Result::Err(bincode::error::DecodeError::EmptyEnum { type_name: core::any::type_name::<Self>() })" ) ?;
209+ } else {
210+ fn_builder
211+ . push_parsed (
212+ "let variant_index = <u32 as bincode::Decode>::decode(&mut decoder)?;" ,
213+ ) ?;
214+ fn_builder. push_parsed ( "match variant_index" ) ?;
215+ fn_builder. group ( Delimiter :: Brace , |variant_case| {
216+ for ( mut variant_index, variant) in self . iter_fields ( ) {
217+ // idx => Ok(..)
218+ if variant_index. len ( ) > 1 {
219+ variant_case. push_parsed ( "x if x == " ) ?;
220+ variant_case. extend ( variant_index) ;
221+ } else {
222+ variant_case. push ( variant_index. remove ( 0 ) ) ;
223+ }
224+ variant_case. puncts ( "=>" ) ;
225+ variant_case. ident_str ( "Ok" ) ;
226+ variant_case. group ( Delimiter :: Parenthesis , |variant_case_body| {
227+ // Self::Variant { }
228+ // Self::Variant { 0: ..., 1: ... 2: ... },
229+ // Self::Variant { a: ..., b: ... c: ... },
230+ variant_case_body. ident_str ( "Self" ) ;
231+ variant_case_body. puncts ( "::" ) ;
232+ variant_case_body. ident ( variant. name . clone ( ) ) ;
221233
222- variant_case_body. group ( Delimiter :: Brace , |variant_body| {
223- let is_tuple = matches ! ( variant. fields, Fields :: Tuple ( _) ) ;
224- for ( idx, field) in variant. fields . names ( ) . into_iter ( ) . enumerate ( ) {
225- if is_tuple {
226- variant_body. lit_usize ( idx) ;
227- } else {
228- variant_body. ident ( field. unwrap_ident ( ) . clone ( ) ) ;
234+ variant_case_body. group ( Delimiter :: Brace , |variant_body| {
235+ let is_tuple = matches ! ( variant. fields, Fields :: Tuple ( _) ) ;
236+ for ( idx, field) in variant. fields . names ( ) . into_iter ( ) . enumerate ( ) {
237+ if is_tuple {
238+ variant_body. lit_usize ( idx) ;
239+ } else {
240+ variant_body. ident ( field. unwrap_ident ( ) . clone ( ) ) ;
241+ }
242+ variant_body. punct ( ':' ) ;
243+ if field. attributes ( ) . has_attribute ( FieldAttribute :: WithSerde ) ? {
244+ variant_body
245+ . push_parsed ( "<bincode::serde::Compat<_> as bincode::Decode>::decode(&mut decoder)?.0," ) ?;
246+ } else {
247+ variant_body
248+ . push_parsed ( "bincode::Decode::decode(&mut decoder)?," ) ?;
249+ }
229250 }
230- variant_body. punct ( ':' ) ;
231- if field. attributes ( ) . has_attribute ( FieldAttribute :: WithSerde ) ? {
232- variant_body
233- . push_parsed ( "<bincode::serde::Compat<_> as bincode::Decode>::decode(&mut decoder)?.0," ) ?;
234- } else {
235- variant_body
236- . push_parsed ( "bincode::Decode::decode(&mut decoder)?," ) ?;
237- }
238- }
251+ Ok ( ( ) )
252+ } ) ?;
239253 Ok ( ( ) )
240254 } ) ?;
241- Ok ( ( ) )
242- } ) ?;
243- variant_case. punct ( ',' ) ;
244- }
255+ variant_case. punct ( ',' ) ;
256+ }
245257
246- // invalid idx
247- self . invalid_variant_case ( & enum_name, variant_case)
248- } ) ?;
258+ // invalid idx
259+ self . invalid_variant_case ( & enum_name, variant_case)
260+ } ) ?;
261+ }
249262 Ok ( ( ) )
250263 } ) ?;
251264 Ok ( ( ) )
@@ -267,54 +280,58 @@ impl DeriveEnum {
267280 . with_arg ( "mut decoder" , "D" )
268281 . with_return_type ( "core::result::Result<Self, bincode::error::DecodeError>" )
269282 . body ( |fn_builder| {
270- fn_builder
271- . push_parsed ( "let variant_index = <u32 as bincode::Decode>::decode(&mut decoder)?;" ) ?;
272- fn_builder. push_parsed ( "match variant_index" ) ?;
273- fn_builder. group ( Delimiter :: Brace , |variant_case| {
274- for ( mut variant_index, variant) in self . iter_fields ( ) {
275- // idx => Ok(..)
276- if variant_index. len ( ) > 1 {
277- variant_case. push_parsed ( "x if x == " ) ?;
278- variant_case. extend ( variant_index) ;
279- } else {
280- variant_case. push ( variant_index. remove ( 0 ) ) ;
281- }
282- variant_case. puncts ( "=>" ) ;
283- variant_case. ident_str ( "Ok" ) ;
284- variant_case. group ( Delimiter :: Parenthesis , |variant_case_body| {
285- // Self::Variant { }
286- // Self::Variant { 0: ..., 1: ... 2: ... },
287- // Self::Variant { a: ..., b: ... c: ... },
288- variant_case_body. ident_str ( "Self" ) ;
289- variant_case_body. puncts ( "::" ) ;
290- variant_case_body. ident ( variant. name . clone ( ) ) ;
283+ if self . variants . is_empty ( ) {
284+ fn_builder. push_parsed ( "core::result::Result::Err(bincode::error::DecodeError::EmptyEnum { type_name: core::any::type_name::<Self>() })" ) ?;
285+ } else {
286+ fn_builder
287+ . push_parsed ( "let variant_index = <u32 as bincode::Decode>::decode(&mut decoder)?;" ) ?;
288+ fn_builder. push_parsed ( "match variant_index" ) ?;
289+ fn_builder. group ( Delimiter :: Brace , |variant_case| {
290+ for ( mut variant_index, variant) in self . iter_fields ( ) {
291+ // idx => Ok(..)
292+ if variant_index. len ( ) > 1 {
293+ variant_case. push_parsed ( "x if x == " ) ?;
294+ variant_case. extend ( variant_index) ;
295+ } else {
296+ variant_case. push ( variant_index. remove ( 0 ) ) ;
297+ }
298+ variant_case. puncts ( "=>" ) ;
299+ variant_case. ident_str ( "Ok" ) ;
300+ variant_case. group ( Delimiter :: Parenthesis , |variant_case_body| {
301+ // Self::Variant { }
302+ // Self::Variant { 0: ..., 1: ... 2: ... },
303+ // Self::Variant { a: ..., b: ... c: ... },
304+ variant_case_body. ident_str ( "Self" ) ;
305+ variant_case_body. puncts ( "::" ) ;
306+ variant_case_body. ident ( variant. name . clone ( ) ) ;
291307
292- variant_case_body. group ( Delimiter :: Brace , |variant_body| {
293- let is_tuple = matches ! ( variant. fields, Fields :: Tuple ( _) ) ;
294- for ( idx, field) in variant. fields . names ( ) . into_iter ( ) . enumerate ( ) {
295- if is_tuple {
296- variant_body. lit_usize ( idx) ;
297- } else {
298- variant_body. ident ( field. unwrap_ident ( ) . clone ( ) ) ;
308+ variant_case_body. group ( Delimiter :: Brace , |variant_body| {
309+ let is_tuple = matches ! ( variant. fields, Fields :: Tuple ( _) ) ;
310+ for ( idx, field) in variant. fields . names ( ) . into_iter ( ) . enumerate ( ) {
311+ if is_tuple {
312+ variant_body. lit_usize ( idx) ;
313+ } else {
314+ variant_body. ident ( field. unwrap_ident ( ) . clone ( ) ) ;
315+ }
316+ variant_body. punct ( ':' ) ;
317+ if field. attributes ( ) . has_attribute ( FieldAttribute :: WithSerde ) ? {
318+ variant_body
319+ . push_parsed ( "<bincode::serde::BorrowCompat<_> as bincode::BorrowDecode>::borrow_decode(&mut decoder)?.0," ) ?;
320+ } else {
321+ variant_body. push_parsed ( "bincode::de::BorrowDecode::borrow_decode(&mut decoder)?," ) ?;
322+ }
299323 }
300- variant_body. punct ( ':' ) ;
301- if field. attributes ( ) . has_attribute ( FieldAttribute :: WithSerde ) ? {
302- variant_body
303- . push_parsed ( "<bincode::serde::BorrowCompat<_> as bincode::BorrowDecode>::borrow_decode(&mut decoder)?.0," ) ?;
304- } else {
305- variant_body. push_parsed ( "bincode::de::BorrowDecode::borrow_decode(&mut decoder)?," ) ?;
306- }
307- }
324+ Ok ( ( ) )
325+ } ) ?;
308326 Ok ( ( ) )
309327 } ) ?;
310- Ok ( ( ) )
311- } ) ?;
312- variant_case. punct ( ',' ) ;
313- }
328+ variant_case. punct ( ',' ) ;
329+ }
314330
315- // invalid idx
316- self . invalid_variant_case ( & enum_name, variant_case)
317- } ) ?;
331+ // invalid idx
332+ self . invalid_variant_case ( & enum_name, variant_case)
333+ } ) ?;
334+ }
318335 Ok ( ( ) )
319336 } ) ?;
320337 Ok ( ( ) )
0 commit comments