From edb53a242c75a411facb6a702cfce3dff6367614 Mon Sep 17 00:00:00 2001 From: Mingun Date: Sun, 28 May 2023 18:52:31 +0500 Subject: [PATCH] Change Tuple1as0(Skipped) representation: newtype -> tuple(0), similar to Tuple0() struct A side-effect: Tuple2as1(Skipped, x) now also can be deserialized using visit_newtype_struct Changes in generated code (see the file attached to PR): Tuple1as0: Tuple1as0Default: Tuple1as0With: removed visit_newtype_struct, *_newtype_struct -> *_tuple_struct(0) Tuple2as1: Tuple2as1Default: Tuple2as1With: added visit_newtype_struct This commit fixes compilation error and actually fixes the issue as it was reported in #2105 --- serde_derive/src/de.rs | 37 ++++++++++++++--------------------- serde_derive/src/ser.rs | 5 +++++ test_suite/tests/test_skip.rs | 3 +-- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index f99945744..951c36eac 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -508,7 +508,7 @@ fn deserialize_tuple( let nfields = fields.len(); let visit_newtype_struct = match form { - TupleForm::Tuple if nfields == 1 => { + TupleForm::Tuple if field_count == 1 => { let visit_newtype_struct = Stmts(read_fields_in_order( &type_path, params, @@ -564,7 +564,7 @@ fn deserialize_tuple( } }; let dispatch = match form { - TupleForm::Tuple if nfields == 1 => { + TupleForm::Tuple if field_count != 0 && nfields == 1 => { let type_name = cattrs.name().deserialize_name(); quote! { _serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr) @@ -642,34 +642,27 @@ fn deserialize_tuple_in_place( let nfields = fields.len(); - let visit_newtype_struct = if nfields == 1 { + let visit_newtype_struct = if field_count == 1 { // We deserialize newtype, so only one field is not skipped let index = fields .iter() .position(|field| !field.attrs.skip_deserializing()) - .unwrap_or(0); - let index = Index::from(index); + .map(Index::from) + .unwrap(); let mut deserialize = quote! { _serde::Deserialize::deserialize_in_place(__e, &mut self.place.#index) }; - let write_defaults = fields.iter().enumerate().filter_map(|(index, field)| { - if field.attrs.skip_deserializing() { - let index = Index::from(index); - let default = Expr(expr_is_missing(field, cattrs)); - return Some(quote!(self.place.#index = #default;)); - } - None - }); - // If there are no deserialized fields, write only defaults - if field_count == 0 { - deserialize = quote! { - #(#write_defaults)* - _serde::__private::Ok(()) - } - } else // Deserialize and write defaults if at least one field is skipped, // otherwise only deserialize - if nfields > field_count { + if nfields > 1 { + let write_defaults = fields.iter().enumerate().filter_map(|(index, field)| { + if field.attrs.skip_deserializing() { + let index = Index::from(index); + let default = Expr(expr_is_missing(field, cattrs)); + return Some(quote!(self.place.#index = #default;)); + } + None + }); deserialize = quote! { match #deserialize { _serde::__private::Ok(_) => { @@ -706,7 +699,7 @@ fn deserialize_tuple_in_place( }; let type_name = cattrs.name().deserialize_name(); - let dispatch = if nfields == 1 { + let dispatch = if field_count != 0 && nfields == 1 { quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr)) } else { quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #field_count, #visitor_expr)) diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index dc02466f5..8ea2f5f2c 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -228,6 +228,11 @@ fn serialize_newtype_struct( field: &Field, cattrs: &attr::Container, ) -> Fragment { + // For `struct Tuple1as0(#[serde(skip)] u8);` cases + if field.attrs.skip_serializing() { + return serialize_tuple_struct(params, &[], cattrs); + } + let type_name = cattrs.name().serialize_name(); let mut field_expr = get_member( diff --git a/test_suite/tests/test_skip.rs b/test_suite/tests/test_skip.rs index c8c1ddd55..8d867000b 100644 --- a/test_suite/tests/test_skip.rs +++ b/test_suite/tests/test_skip.rs @@ -87,7 +87,6 @@ mod tuple_struct { ); } - /* FIXME: compilation error: https://github.com/serde-rs/serde/issues/2105 #[test] fn tuple1as0() { /// This newtype struct in the serialized form the same as `struct Tuple0();` @@ -107,7 +106,7 @@ mod tuple_struct { Token::TupleStructEnd, ], ); - }*/ + } #[test] fn tuple2as0() {