Skip to content

Commit 89c8d85

Browse files
allow Deserialize derive to handle generic unit structs
1 parent 6502838 commit 89c8d85

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

serde_derive/src/de.rs

+17-4
Original file line numberDiff line numberDiff line change
@@ -410,16 +410,29 @@ fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fra
410410
let this_type = &params.this_type;
411411
let this_value = &params.this_value;
412412
let type_name = cattrs.name().deserialize_name();
413+
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
414+
split_with_de_lifetime(params);
415+
let delife = params.borrowed.de_lifetime();
413416

414417
let expecting = format!("unit struct {}", params.type_name());
415418
let expecting = cattrs.expecting().unwrap_or(&expecting);
416419

420+
let visitor_expr = quote! {
421+
__Visitor {
422+
marker: _serde::__private::PhantomData::<#this_type #ty_generics>,
423+
lifetime: _serde::__private::PhantomData,
424+
}
425+
};
426+
417427
quote_block! {
418428
#[doc(hidden)]
419-
struct __Visitor;
429+
struct __Visitor #de_impl_generics #where_clause {
430+
marker: _serde::__private::PhantomData<#this_type #ty_generics>,
431+
lifetime: _serde::__private::PhantomData<&#delife ()>,
432+
}
420433

421-
impl<'de> _serde::de::Visitor<'de> for __Visitor {
422-
type Value = #this_type;
434+
impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
435+
type Value = #this_type #ty_generics;
423436

424437
fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
425438
_serde::__private::Formatter::write_str(__formatter, #expecting)
@@ -434,7 +447,7 @@ fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fra
434447
}
435448
}
436449

437-
_serde::Deserializer::deserialize_unit_struct(__deserializer, #type_name, __Visitor)
450+
_serde::Deserializer::deserialize_unit_struct(__deserializer, #type_name, #visitor_expr)
438451
}
439452
}
440453

test_suite/tests/test_de.rs

+14
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ mod macros;
4646
#[derive(Copy, Clone, PartialEq, Debug, Deserialize)]
4747
struct UnitStruct;
4848

49+
#[derive(Copy, Clone, PartialEq, Debug, Deserialize)]
50+
struct GenericUnitStruct<const N: u8>;
51+
4952
#[derive(PartialEq, Debug, Deserialize)]
5053
struct NewtypeStruct(i32);
5154

@@ -883,6 +886,17 @@ fn test_unit_struct() {
883886
test(UnitStruct, &[Token::UnitStruct { name: "UnitStruct" }]);
884887
}
885888

889+
#[test]
890+
fn test_generic_unit_struct() {
891+
test(GenericUnitStruct::<8>, &[Token::Unit]);
892+
test(
893+
GenericUnitStruct::<8>,
894+
&[Token::UnitStruct {
895+
name: "GenericUnitStruct",
896+
}],
897+
);
898+
}
899+
886900
#[test]
887901
fn test_newtype_struct() {
888902
test(

0 commit comments

Comments
 (0)