Improve error for struct deserialized from array that is too short

This commit is contained in:
David Tolnay 2018-05-08 12:03:35 -07:00
parent 67777eb585
commit 4ad140ea70
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
2 changed files with 20 additions and 8 deletions

View File

@ -427,7 +427,9 @@ fn deserialize_tuple(
None None
}; };
let visit_seq = Stmts(deserialize_seq(&type_path, params, fields, false, cattrs)); let visit_seq = Stmts(deserialize_seq(
&type_path, params, fields, false, cattrs, &expecting,
));
let visitor_expr = quote! { let visitor_expr = quote! {
__Visitor { __Visitor {
@ -511,7 +513,7 @@ fn deserialize_tuple_in_place(
None None
}; };
let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs)); let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, &expecting));
let visitor_expr = quote! { let visitor_expr = quote! {
__Visitor { __Visitor {
@ -577,6 +579,7 @@ fn deserialize_seq(
fields: &[Field], fields: &[Field],
is_struct: bool, is_struct: bool,
cattrs: &attr::Container, cattrs: &attr::Container,
expecting: &str,
) -> Fragment { ) -> Fragment {
let vars = (0..fields.len()).map(field_i as fn(_) -> _); let vars = (0..fields.len()).map(field_i as fn(_) -> _);
@ -586,7 +589,11 @@ fn deserialize_seq(
.iter() .iter()
.filter(|field| !field.attrs.skip_deserializing()) .filter(|field| !field.attrs.skip_deserializing())
.count(); .count();
let expecting = format!("tuple of {} elements", deserialized_count); let expecting = if deserialized_count == 1 {
format!("{} with 1 element", expecting)
} else {
format!("{} with {} elements", expecting, deserialized_count)
};
let mut index_in_seq = 0_usize; let mut index_in_seq = 0_usize;
let let_values = vars.clone().zip(fields).map(|(var, field)| { let let_values = vars.clone().zip(fields).map(|(var, field)| {
@ -671,6 +678,7 @@ fn deserialize_seq_in_place(
params: &Parameters, params: &Parameters,
fields: &[Field], fields: &[Field],
cattrs: &attr::Container, cattrs: &attr::Container,
expecting: &str,
) -> Fragment { ) -> Fragment {
let vars = (0..fields.len()).map(field_i as fn(_) -> _); let vars = (0..fields.len()).map(field_i as fn(_) -> _);
@ -680,7 +688,11 @@ fn deserialize_seq_in_place(
.iter() .iter()
.filter(|field| !field.attrs.skip_deserializing()) .filter(|field| !field.attrs.skip_deserializing())
.count(); .count();
let expecting = format!("tuple of {} elements", deserialized_count); let expecting = if deserialized_count == 1 {
format!("{} with 1 element", expecting)
} else {
format!("{} with {} elements", expecting, deserialized_count)
};
let mut index_in_seq = 0usize; let mut index_in_seq = 0usize;
let write_values = vars.clone() let write_values = vars.clone()
@ -852,7 +864,7 @@ fn deserialize_struct(
None => format!("struct {}", params.type_name()), None => format!("struct {}", params.type_name()),
}; };
let visit_seq = Stmts(deserialize_seq(&type_path, params, fields, true, cattrs)); let visit_seq = Stmts(deserialize_seq(&type_path, params, fields, true, cattrs, &expecting));
let (field_visitor, fields_stmt, visit_map) = if cattrs.has_flatten() { let (field_visitor, fields_stmt, visit_map) = if cattrs.has_flatten() {
deserialize_struct_as_map_visitor(&type_path, params, fields, cattrs) deserialize_struct_as_map_visitor(&type_path, params, fields, cattrs)
@ -991,7 +1003,7 @@ fn deserialize_struct_in_place(
None => format!("struct {}", params.type_name()), None => format!("struct {}", params.type_name()),
}; };
let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs)); let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, &expecting));
let (field_visitor, fields_stmt, visit_map) = let (field_visitor, fields_stmt, visit_map) =
deserialize_struct_as_struct_in_place_visitor(params, fields, cattrs); deserialize_struct_as_struct_in_place_visitor(params, fields, cattrs);

View File

@ -1300,7 +1300,7 @@ fn test_invalid_length_enum() {
Token::I32(1), Token::I32(1),
Token::TupleVariantEnd, Token::TupleVariantEnd,
], ],
"invalid length 1, expected tuple of 3 elements", "invalid length 1, expected tuple variant InvalidLengthEnum::A with 3 elements",
); );
assert_de_tokens_error::<InvalidLengthEnum>( assert_de_tokens_error::<InvalidLengthEnum>(
&[ &[
@ -1312,7 +1312,7 @@ fn test_invalid_length_enum() {
Token::I32(1), Token::I32(1),
Token::TupleVariantEnd, Token::TupleVariantEnd,
], ],
"invalid length 1, expected tuple of 2 elements", "invalid length 1, expected tuple variant InvalidLengthEnum::B with 2 elements",
); );
} }