Repository: serde-rs/serde
File: serde_codegen/src/de.rs (Rust)

Code before:
                let default = expr_is_missing(cx, builder, &field.attrs);
                quote_stmt!(cx,
                    let $name = $default;
                ).unwrap()
            } else {
                let visit = match field.attrs.deserialize_with() {
                    None => {
                        let field_ty = &field.ty;
                        quote_expr!(cx, try!(visitor.visit::<$field_ty>()))
                    }
                    Some(path) => {
                        let (wrapper, wrapper_impl, wrapper_ty) = wrap_deserialize_with(
                            cx, builder, type_ident, impl_generics, &field.ty, path);
                        quote_expr!(cx, {
                            $wrapper
                            $wrapper_impl
                            try!(visitor.visit::<$wrapper_ty>()).map(|wrap| wrap.value)
                        })
                    }
                };
                quote_stmt!(cx,
                    let $name = match $visit {
                        Some(value) => { value },
                        None => {
                            return Err(_serde::de::Error::end_of_stream());
                        }
                    };
                ).unwrap()
            }
        })
        .collect();

    let result = if is_struct {
        builder.expr().struct_path(type_path)
            .with_id_exprs(
                fields.iter()
                    .enumerate()
                    .map(|(i, field)| {
                        (
                            match field.ident {
                                Some(name) => name.clone(),
                                None => {
                                    cx.span_bug(field.span, "struct contains unnamed fields")
                                }
                            },
                            builder.expr().id(format!("__field{}", i)),
                        )
                    })
            )
            .build()
    } else {

Review comment (suggestion):
`$i` is the index in the struct, not index in the input sequence. The second unit test tests this. With `$i` it would return `InvalidLength(2)` instead of `InvalidLength(1)`.


Code after:
            if field.attrs.skip_deserializing() {
                let default = expr_is_missing(cx, builder, &field.attrs);
                quote_stmt!(cx,
                    let $name = $default;
                ).unwrap()
            } else {
                let visit = match field.attrs.deserialize_with() {
                    None => {
                        let field_ty = &field.ty;
                        quote_expr!(cx, try!(visitor.visit::<$field_ty>()))
                    }
                    Some(path) => {
                        let (wrapper, wrapper_impl, wrapper_ty) = wrap_deserialize_with(
                            cx, builder, type_ident, impl_generics, &field.ty, path);
                        quote_expr!(cx, {
                            $wrapper
                            $wrapper_impl
                            try!(visitor.visit::<$wrapper_ty>()).map(|wrap| wrap.value)
                        })
                    }
                };
                let assign = quote_stmt!(cx,
                    let $name = match $visit {
                        Some(value) => { value },
                        None => {
                            return Err(_serde::de::Error::invalid_length($index_in_seq));
                        }
                    };
                ).unwrap();
                index_in_seq += 1;
                assign
            }
        })
        .collect();

    let result = if is_struct {
        builder.expr().struct_path(type_path)
            .with_id_exprs(
                fields.iter()
                    .enumerate()
                    .map(|(i, field)| {
                        (
                            match field.ident {
                                Some(name) => name.clone(),
                                None => {
                                    cx.span_bug(field.span, "struct contains unnamed fields")
                                }
                            },
                            builder.expr().id(format!("__field{}", i)),
                        )
                    })