1 个不稳定版本

0.1.3 2019年10月21日

#11#conditional-compilation

Apache-2.0

22KB

dirmod

Travis-CI crates.io crates.io docs.rs GitHub

厌倦了在 mod.rs 中编写和更新所有 mod 语句?用 dirmod 来生成它们。

dirmod 会扫描你的目录,并通过简单的宏调用自动生成相应的 mod 语句

dirmod::all!();

就这么简单!

(注意:dirmod 是为 Rust 2018 版本 设计的,因此宏的名称简单且具有歧义,如 allos 等。建议以完全限定方式调用宏,例如 dirmod::all!()dirmod::os!() 等,以提高清晰度。不推荐使用旧的 #[macro_use] extern crate dirmod; 语法。)

可见性

默认可见性

所有模块都可以设置为共同的可见性,例如 pub modpub(self) mod 等,任君选择

dirmod::all!(default pub);

重新导出

您还可以将所有模块设置为私有,并设置 重新导出 项的可见性

dirmod::all!(default pub use);

单独文件默认值和目录默认值

处理文件模块和目录模块可能很常见

dirmod::all!(default file pub use; default dir pub);

此操作将重新导出文件模块中的所有项,并将所有目录模块按名称公开。 (此行为类似于 Go 中的包系统)

默认行为

如果没有提供 default 参数,则默认选择为 default file priv use; default dir priv

单个可见性

如果几十个模块中有个别模块需要特殊可见性配置,也可以这样写

dirmod::all!(default pub; priv foo, bar);

然后所有模块都有 pub 可见性,除了 foobar,它们是私有的。

同样,如果所有模块都公开重新导出,而 foobar 只作为模块导出

dirmod::all!(default pub use; pub foo, bar);

条件编译

但我使用 mod 来实现条件编译!

没问题,dirmod 为一些惯用风格生成 cfg 属性。

  • 一个目录,每个模块名称是功能名称(例如:#[cfg(feature = "foo")] mod foo;
  • 一个目录,每个模块名称是操作系统/操作系统家族名称(例如:#[cfg(target_family = "unix")] mod unix;

可以通过调用 dirmod::os!()dirmod::family!()dirmod::feature!() 来实现。

由于同一模块的不同操作系统变体可能公开相同的 API,因此编写

dirmod::os!(pub use);

如果没有任何模块支持当前操作系统,可以触发编译错误

dirmod::os!(pub use ||);

或使用自定义错误信息

dirmod::os!(pub use || "custom error message");

请注意,在 dirmod::feature! 上使用 || 没有意义,因为 Cargo 功能是增量且不应受数量限制。

提交一个问题 如果我遗漏了任何常见风格!

但我对 xxxx 情况仍然不满意!

没问题,你不需要为每个模块使用 dirmoddirmod::all!() 有一个 except 参数,可以排除某些模块。由于宏只是简单地生成 mod 语句,因此在宏调用之前/之后添加更多项是完全可行的。

dirmod::all!(except corge, grault);

文档

直接在模块中编写文档,而不是在 mod.rs 中编写。除了 dirmod 约束之外,还有一些优点

  • 避免在单个 mod.rs 中混合大量文档。更易于导航!
  • 在模块内部编写文档比引用父模块更为相关。

要为模块编写文档,请在模块顶部使用此语法(在其他任何项之前)

//! Yay, I'm now describing myself!
//! I finally have my own place!

支持的 Rust 版本

由于检测源文件需要 proc_macro_span 功能,因此需要 Rust Nightly 来编译此软件包。

示例

请参阅 testcrate 目录,其中演示了使用 dirmod::all!dirmod::family!

语法参考

BNF语法参考可在 syntax.bnf 找到。

已知未解决的问题

rustfmt 支持

rustfmtcargo fmt 通过检测包含文件中的直接 mod 语句来直接操作入口点包含的模块。由于 rustfmt 不展开(甚至编译)宏(已知问题),由 dirmod 包含的模块将不会被格式化。

目前最直接的替代方案是在Linux shell上启用 shopt -s globstar 运行 rustfmt src/**/*.rs

错误报告

Rust编译器可能无法正确定位语法错误位置(已知问题)。然而,这个问题仅在语法错误与前置 #[] 有关的情况下重现,这可能是一个内部属性。

依赖关系

~1.5MB
~38K SLoC