Added support for borrowing when flattening

This commit is contained in:
Armin Ronacher 2018-03-20 15:19:36 +01:00
parent 695c3eedcb
commit e4ef087735
2 changed files with 119 additions and 2 deletions

View File

@ -1875,7 +1875,9 @@ fn deserialize_identifier(
collect_other_fields: bool
) -> Fragment {
let field_strs = fields.iter().map(|&(ref name, _)| name);
let field_borrowed_strs = fields.iter().map(|&(ref name, _)| name);
let field_bytes = fields.iter().map(|&(ref name, _)| Literal::byte_string(name.as_bytes()));
let field_borrowed_bytes = fields.iter().map(|&(ref name, _)| Literal::byte_string(name.as_bytes()));
let constructors: &Vec<_> = &fields
.iter()
@ -1997,15 +1999,22 @@ fn deserialize_identifier(
})
};
let (value_as_str_content, value_as_bytes_content) = if !collect_other_fields {
(None, None)
let (value_as_str_content, value_as_borrowed_str_content,
value_as_bytes_content, value_as_borrowed_bytes_content) = if !collect_other_fields {
(None, None, None, None)
} else {
(
Some(quote! {
let __value = _serde::private::de::Content::String(__value.to_string());
}),
Some(quote! {
let __value = _serde::private::de::Content::Str(__value);
}),
Some(quote! {
let __value = _serde::private::de::Content::ByteBuf(__value.to_vec());
}),
Some(quote! {
let __value = _serde::private::de::Content::Bytes(__value);
})
)
};
@ -2043,6 +2052,35 @@ fn deserialize_identifier(
}
}
fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error
{
match __value {
#(
#field_borrowed_strs => _serde::export::Ok(#constructors),
)*
_ => {
#value_as_borrowed_str_content
#fallthrough_arm
}
}
}
fn visit_borrowed_bytes<__E>(self, __value: &'de [u8]) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error
{
match __value {
#(
#field_borrowed_bytes => _serde::export::Ok(#constructors),
)*
_ => {
#bytes_to_str
#value_as_borrowed_bytes_content
#fallthrough_arm
}
}
}
fn visit_bytes<__E>(self, __value: &[u8]) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error
{

View File

@ -1684,3 +1684,82 @@ fn test_non_string_keys() {
],
);
}
#[test]
fn test_lifetime_propagation_for_flatten() {
#[derive(Deserialize, Serialize, Debug, PartialEq)]
struct A<T> {
#[serde(flatten)]
t: T,
}
#[derive(Deserialize, Serialize, Debug, PartialEq)]
struct B<'a> {
#[serde(flatten, borrow)]
t: HashMap<&'a str, u32>,
}
#[derive(Deserialize, Serialize, Debug, PartialEq)]
struct C<'a> {
#[serde(flatten, borrow)]
t: HashMap<&'a [u8], u32>,
}
let mut owned_map = HashMap::new();
owned_map.insert("x".to_string(), 42u32);
assert_tokens(
&A { t: owned_map },
&[
Token::Map { len: None },
Token::Str("x"),
Token::U32(42),
Token::MapEnd,
],
);
let mut borrowed_map = HashMap::new();
borrowed_map.insert("x", 42u32);
assert_ser_tokens(
&B { t: borrowed_map.clone() },
&[
Token::Map { len: None },
Token::BorrowedStr("x"),
Token::U32(42),
Token::MapEnd,
],
);
assert_de_tokens(
&B { t: borrowed_map },
&[
Token::Map { len: None },
Token::BorrowedStr("x"),
Token::U32(42),
Token::MapEnd,
],
);
let mut borrowed_map = HashMap::new();
borrowed_map.insert(&b"x"[..], 42u32);
assert_ser_tokens(
&C { t: borrowed_map.clone() },
&[
Token::Map { len: None },
Token::Seq { len: Some(1) },
Token::U8(120),
Token::SeqEnd,
Token::U32(42),
Token::MapEnd,
],
);
assert_de_tokens(
&C { t: borrowed_map },
&[
Token::Map { len: None },
Token::BorrowedBytes(b"x"),
Token::U32(42),
Token::MapEnd,
],
);
}