为什么这种重复模式在 Rust 宏中不起作用?
Why doesn't this repetition pattern work in Rust macro?
我正在尝试编写一个宏来泛化任何结构的 serde_yaml 反序列化,这样我就不必一遍又一遍地重写相同的东西。现在唯一让我感到困惑的是模式中的重复。
宏:
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)*))
}
}
}
}
}
};
}
通话之一:
impl_struct_deserialization!(
GBox {
center: Vec3f,
material: Material,
radius: f32
}
);
错误(除了第一个之外的每个字段都重复):
谢谢!
UPD:使用this作为参考
该特定错误是由于靠近底部的一行中缺少逗号造成的:
Ok($struct_type::new($($field_name),*))
// ^
我正在尝试编写一个宏来泛化任何结构的 serde_yaml 反序列化,这样我就不必一遍又一遍地重写相同的东西。现在唯一让我感到困惑的是模式中的重复。
宏:
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)*))
}
}
}
}
}
};
}
通话之一:
impl_struct_deserialization!(
GBox {
center: Vec3f,
material: Material,
radius: f32
}
);
错误(除了第一个之外的每个字段都重复):
谢谢!
UPD:使用this作为参考
该特定错误是由于靠近底部的一行中缺少逗号造成的:
Ok($struct_type::new($($field_name),*))
// ^