简体   繁体   English

为什么这种重复模式在 Rust 宏中不起作用?

[英]Why doesn't this repetition pattern work in Rust macro?

I'm trying to write a macro that generalizes serde_yaml deserialization for any struct so I don't have to rewrite the same thing over and over again.我正在尝试编写一个宏来概括任何结构的 serde_yaml 反序列化,这样我就不必一遍又一遍地重写相同的东西。 The only thing that is messign me up right now is the repetition inside a pattern.现在唯一让我感到困惑的是模式中的重复。

Macro:宏观:

macro_rules! impl_struct_deserialization {
    (
        $struct_type: path {
            $(
                $field_name:ident : $field_type:path
            ),*
        }
    ) => {
        paste! {
            impl<'de> Deserialize<'de> for $struct_type {
                fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
                where D: Deserializer<'de> {
                    #[derive(Deserialize)]
                    #[serde(field_identifier, rename_all = "lowercase")]
                    enum Field {
                        $(
                        [<$field_name:camel>]
                        ),*
                    }

                    struct [<$struct_type Visitor>];

                    impl<'de> Visitor<'de> for [<$struct_type Visitor>] {
                        type Value = $struct_type;

                        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                            formatter.write_str(&("struct "
                                    .to_owned()
                                    .push_str(&stringify!($struct_type))
                                )
                            );
                        }

                        fn visit_map<V>(self, mut map: V) -> Result<$struct_type, V::Error>
                        where V: MapAccess<'de> {
                            $(let mut $field_name: Option<$field_type> = None;)*

                            while let Some(key) = map.next_key()? {
                                match key {
                                    $(Field::[<$field_type:camel>] => {
                                        if $field_name.is_some() {
                                            return Err(serde::de::Error::duplicate_field(stringify!($field_name)));
                                        }
                                        $field_name = Some(map.next_value()?);
                                    })*
                                }
                            }

                            $(
                            let $field_name = $field_name.ok_or_else(|| serde::de::Error::missing_field(stringify!($field_name)))?;
                            )*

                            Ok($struct_type::new($($field_name)*))
                        }
                    }
                }
            }
        }
    };
}

One of the calls:其中一个电话:

impl_struct_deserialization!(
    GBox {
        center: Vec3f,
        material: Material,
        radius: f32
    }
);

Error (repeats for every field apart from 1st):错误(除了第一个字段之外的每个字段都重复): 有问题的错误

Thank you!谢谢你!

UPD: used this as a reference UPD:以此为参考

That specific error is due to a missing comma in a line near the bottom:该特定错误是由于靠近底部的一行中缺少逗号造成的:

Ok($struct_type::new($($field_name),*))
//                                 ^

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM