1 个不稳定版本
0.1.3 | 2019年10月21日 |
---|
#11 在 #conditional-compilation
22KB
dirmod
厌倦了在 mod.rs 中编写和更新所有 mod
语句?用 dirmod
来生成它们。
dirmod
会扫描你的目录,并通过简单的宏调用自动生成相应的 mod
语句
dirmod::all!();
就这么简单!
(注意:
dirmod
是为 Rust 2018 版本 设计的,因此宏的名称简单且具有歧义,如all
、os
等。建议以完全限定方式调用宏,例如dirmod::all!()
、dirmod::os!()
等,以提高清晰度。不推荐使用旧的#[macro_use] extern crate dirmod;
语法。)
可见性
默认可见性
所有模块都可以设置为共同的可见性,例如 pub mod
或 pub(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
可见性,除了 foo
和 bar
,它们是私有的。
同样,如果所有模块都公开重新导出,而 foo
和 bar
只作为模块导出
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 情况仍然不满意!
没问题,你不需要为每个模块使用 dirmod
。 dirmod::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
支持
rustfmt
和 cargo fmt
通过检测包含文件中的直接 mod
语句来直接操作入口点包含的模块。由于 rustfmt
不展开(甚至编译)宏(已知问题),由 dirmod
包含的模块将不会被格式化。
目前最直接的替代方案是在Linux shell上启用 shopt -s globstar
运行 rustfmt src/**/*.rs
。
错误报告
Rust编译器可能无法正确定位语法错误位置(已知问题)。然而,这个问题仅在语法错误与前置 #[]
有关的情况下重现,这可能是一个内部属性。
依赖关系
~1.5MB
~38K SLoC