diff --git a/src/lib.rs b/src/lib.rs index dee75ad..8a90962 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -181,12 +181,45 @@ fn match_fields(fields: &[parse::Field], offset: usize) -> Vec { + let ty = &field.ty; + quote!({ + struct __DeserializeWith< 'de> { + value: #ty, + lifetime: ::core::marker::PhantomData<&'de ()>, + } + impl<'de> serde::Deserialize<'de> for __DeserializeWith<'de> { + fn deserialize<__D>( + __deserializer: __D, + ) -> Result + where + __D: serde::Deserializer<'de>, + { + + Ok(__DeserializeWith { + value: #f(__deserializer)?, + lifetime: ::core::marker::PhantomData, + }) + } + } + + let __DeserializeWith { value, lifetime: _ } = map.next_value()?; + value + } + ) + } + None => quote!(map.next_value()?), + }; + quote! { #index => { if #ident.is_some() { return Err(serde::de::Error::duplicate_field(#label)); } - #ident = Some(map.next_value()?); + let next_value = #next_value; + #ident = Some(next_value); }, } }) diff --git a/tests/basics.rs b/tests/basics.rs index 97f0d7e..540fb63 100644 --- a/tests/basics.rs +++ b/tests/basics.rs @@ -418,7 +418,7 @@ mod generics { use heapless::String; use serde_byte_array::ByteArray; use serde_bytes::Bytes; - use serde_test::assert_ser_tokens; + use serde_test::{assert_de_tokens, assert_ser_tokens}; #[derive(PartialEq, Debug, SerializeIndexed, DeserializeIndexed)] #[serde_indexed(offset = 1)] @@ -544,4 +544,25 @@ mod generics { ], ) } + + #[test] + fn deserialize_with() { + #[derive(serde_indexed::DeserializeIndexed, PartialEq, Eq, Debug)] + struct SerializeWith { + #[serde(deserialize_with = "serde_bytes::deserialize")] + data: Vec, + } + + let value = SerializeWith { data: vec![0; 128] }; + + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(1) }, + Token::U64(0), + Token::Bytes(&[0; 128]), + Token::MapEnd, + ], + ) + } }