首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我可以重写这个macro_rules吗?宏以一种适用于锈迹的方式?

我可以重写这个macro_rules吗?宏以一种适用于锈迹的方式?
EN

Stack Overflow用户
提问于 2020-05-28 17:34:18
回答 1查看 657关注 0票数 4

我想使用宏为多个具体类型生成相同的impl块。我的代码目前看起来如下所示:

代码语言:javascript
复制
macro_rules! impl_methods {
    ($ty:ty, {  $($method:item);+} ) => {
        impl $ty { $($method)+ }
    };
    ($ty:ty, $($more:ty),+ {$($method:item);+}) => {
        impl_methods!($ty, {$($method);+});
        impl_methods!($($more),+, {$($method);+});
    };
}

struct Hi;
struct Hello;

impl_methods!(Hi, Hello {
    /// `true` if it works, good
    fn works_good(&self) -> bool {
        true
    };

    /// `true` if rustfmt is working
    fn gets_rustfmt(&self) -> bool {
        false
    }
});

assert!(Hi.works_good() && Hello.works_good());
assert!(!(Hi.gets_rustfmt() | Hello.gets_rustfmt()));

这已经足够好了(生成了内嵌),但是它有一个令人沮丧的问题;在宏中定义的方法不会被rustfmt格式化。

这是一个小问题,但它够烦人的,我对一个解决方案很好奇。我知道,rustfmt将格式化宏的内容,如果这些内容有某种形式(是表达式吗?)因此,例如,将格式化以下宏的内容:

代码语言:javascript
复制
macro_rules! fmt_me {
    ($inner:item) => {
        $inner
    };
}

fmt_me!(fn will_get_formatted() -> bool { true });

所以我希望能有一些方法来写我的宏,

代码语言:javascript
复制
impl_methods!(Hi, Hello {
    fmt_me!(fn my_method(&self) -> bool { true });
    fmt_me!(fn my_other_method(&self) -> bool { false });
});

让每个方法都被锈蚀覆盖。

这个是可能的吗?有什么神奇的咒语能给我带来我想要的可爱的格式吗?

回答

由于下面的答案(来自@seiichi-uchida),我可以使用以下代码来处理这个问题:

代码语言:javascript
复制
macro_rules! impl_methods {
    ($ty:ty, {  $($method:item)+} ) => {
        impl $ty { $($method)+ }
    };
    ($ty:ty, $($more:ty),+, {$($method:item)+}) => {
        impl_methods!($ty, {$($method)+});
        impl_methods!($($more),+, {$($method)+});
    };
}

macro_rules! fmt_me {
    ($inner:item) => {
        $inner
    };
}

// called like:

impl_methods!(Hi, Hello, {
    fmt_me!(fn this_is_a_method(&self) -> bool { true });
    fmt_me!(fn this_is_another_method(&self) -> bool { true });
});
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-29 00:53:19

在最后一个类型和impl块之间添加一个逗号应该可以做到这一点:

代码语言:javascript
复制
impl_methods!(Hi, Hello, {
    fmt_me!(fn my_method(&self) -> bool { true });
    fmt_me!(fn my_other_method(&self) -> bool { false });
});

这将被格式化为:

代码语言:javascript
复制
 impl_methods!(Hi, Hello, {
-    fmt_me!(fn my_method(&self) -> bool { true });
-    fmt_me!(fn my_other_method(&self) -> bool { false });
+    fmt_me!(
+        fn my_method(&self) -> bool {
+            true
+        }
+    );
+    fmt_me!(
+        fn my_other_method(&self) -> bool {
+            false
+        }
+    );
 });

通常,rustfmt只能格式化其参数可以解析为有效的Rust AST节点的宏调用(除了一些例外)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62070972

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档