gpt4 book ai didi

rust - 根据字段类型有条件地生成 From impl

转载 作者:行者123 更新时间:2023-12-02 02:38:53 26 4
gpt4 key购买 nike

我正在尝试创建一个通用实现,用于根据不同的字段类型生成 From/Into。

Link to Playground

我发现了以下问题:

error[E0425]: cannot find value `item` in this scope
--> src/lib.rs:23:21
|
23 | $param: item.$param,
| ^^^^ not found in this scope
...
65 | create_impl! { TargetStruct, InputStruct, { field1: Option<String>, field2: Option<Uuid> }}
| ------------------------------------------------------------------------------------------- in this macro invocation

任何人都可以为我指明正确的方向,告诉我如何让它发挥作用/如果可能的话。此时,我不确定如何将输入参数传递给规则。

谢谢!


#[macro_use]
macro_rules! create_impl {
( @ $target:ident, $input:ident, { } -> ($($result:tt)*) ) => (
impl From<$input> for $target {
fn from(item: $input) -> Self {
Self {
$($result)*
..Default::default()
}
}
});

( @ $target:ident, $input:ident, { $param:ident : Option<Uuid>, $($rest:tt)* } -> ($($result:tt)*) ) => (
create_impl!(@ $target, $input, { $($rest)* } -> (
$($result)*
$param: item.$param.map(|v| v.to_string()),
));
);

( @ $target:ident, $input:ident, { $param:ident : $type:ty, $($rest:tt)* } -> ($($result:tt)*) ) => (
create_impl!(@ $target, $input, { $($rest)* } -> (
$($result)*
$param: item.$param,
));
);


( @ $target:ident, $input:ident, { $param:ident : $type:ty, $($rest:tt)* } -> ($($result:tt)*) ) => (
create_impl!(@ $target, $input, { $($rest)* } -> (
$($result)*
$param: item.$param,
));
);

( $target:ident, $input:ident, { $( $param:ident : $type:ty ),* $(,)* } ) => (
create_impl!(@ $target, $input, { $($param : $type,)* } -> ());
);
}

最佳答案

您可以让 Rust 完成繁重的工作:

macro_rules! memberize_result {
($item: ident, $param:ident : Option<Uuid>) => (
$item.$param.map(|v| v.to_string())
);

($item: ident, $param:ident : Option<String>) => (
$item.$param
);
}

#[macro_use]
macro_rules! create_impl {
( $target:ident, $input:ident, { $( $param:ident : ($($type:tt)*) ),* $(,)* } ) => (
impl From<$input> for $target {
fn from(item: $input) -> Self {
Self {
$($param: memberize_result!(item, $param : $($type)*),)*
..Default::default()
}
}
}
);
}


use uuid::Uuid; // 0.8.1

#[derive(Default)]
pub struct InputStruct {
pub field1: Option<String>,
pub field2: Option<Uuid>,
}

#[derive(Default)]
pub struct TargetStruct {
pub field1: Option<String>,
pub field2: Option<String>,
}

// Trying to turn this into a macro
// impl From<ExampleStruct> for TargetStruct {
// fn from(item: ExampleStruct) -> Self {
// let mut res = Self::default();
// res.field1 = item.field1;
// res.field2 = item.field2.map(|v| v.to_string());
// res
// }
// }

create_impl! { TargetStruct, InputStruct, { field1: (Option<String>), field2: (Option<Uuid>) }}

关于rust - 根据字段类型有条件地生成 From impl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61110492/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com