2 个不稳定版本
0.2.0-alpha.1 | 2019年11月22日 |
---|---|
0.1.4 | 2019年10月21日 |
#16 in #conditional-compilation
在 3 个 crate 中使用 (通过 dirmod)
34KB
665 行
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来编译此crate。
示例
请参阅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
~37K SLoC