【问题标题】:How to reexpose an entire crate inline如何重新暴露整个板条箱内联
【发布时间】:2022-01-24 03:51:46
【问题描述】:

我有一个 proc-macro,它也公开了一些类型,所以我使用以下 crate 结构:

  • foo_core 出口 FooTrait
  • foo_macro(取决于foo_core)导出foo_macro,生成一些实现FooTrait的结构体
  • foo(取决于foo_corefoo_macro)再出口FooTraitfoo_macro

我遇到的问题是重新导出 foo_core 会改变它的路径。

foo_macro 生成的代码大致如下:

struct Bar;

impl ::foo_core::FooTrait for Bar {
  // ...
}

我在foo_macro 中有一堆trybuild 测试通过了,因为foo_core 是一个可用的板条箱。

问题是当我尝试在 foo(或仅依赖于 foo 的 crate 中)编写测试时,我收到错误消息,告诉我找不到 crate foo_core

这对我来说有点道理; foo 的消费者没有明确依赖 foo_core,但如果我的 crate 的用户不必添加 foofoo_core(并确保版本匹配),我会喜欢它,而不是我希望他们能够只添加foo,这样就可以了。

目前,我可以通过foo::foo_core::FooTrait 访问foo_core,但这显然与我的宏生成代码的方式不同(::foo_core::FooTrait)。有没有办法让foo重新导出整个foo_core crate?

如果这不可能,那么处理这种模式的最佳方法是什么?我可以以某种方式让foo_macro 根据它定义的箱子改变它的行为吗?还是应该将所有测试移至foo 而不是foo_macro

Is there a way to have a public trait in a proc-macro crate? an answer to this question提到了这个问题,但只是说“你必须使用完全限定的名称”,但我的理解是这就是路径上领先的::的意思。

这似乎是一种相对常见的模式,所以我希望那里有一个不错的解决方案。

【问题讨论】:

标签: rust rust-cargo


【解决方案1】:

在您的 foo crate 中,您可以使用以下任一方法完全重新导出 foo_core

  • pub extern crate foo_core;
  • pub use foo_core;

使用这些语句中的任何一个,当您的Cargo.toml[dependencies] 部分中只有foo 时,可以通过foo::foo_core:: 访问所有foo_core。然后,您的 proc 宏将发出 ::foo::foo_core:: 路径。这当然要求用户不要直接使用foo_macrofoo_core。但这很常见:通常,人们不应该直接使用宏板条箱,而只能使用“顶级板条箱”。

这是一种常见的模式,不仅适用于您自己的 crate。例如,在我的一个库中,我的 proc 宏生成对 serde 函数(不是我的库)的调用。所以我在我的箱子里pub use serde;,这样我图书馆的用户就不必直接依赖serde

【讨论】:

    猜你喜欢
    • 2015-10-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2012-08-08
    • 1970-01-01
    • 1970-01-01
    • 2017-06-21
    相关资源
    最近更新 更多