10 个不稳定版本 (3 个破坏性更新)
0.4.5 | 2022年4月22日 |
---|---|
0.4.4 | 2022年4月20日 |
0.3.0 | 2022年4月19日 |
0.2.1 | 2022年4月19日 |
0.1.0 | 2022年3月30日 |
#1038 in 开发工具
120KB
2.5K SLoC
flexgen
一个灵活且简单的基于quote的代码生成器,用于创建美观的Rust代码
为什么?
Rust 有两种类型的宏,它们都很受欢迎,但并不总是最佳选择。它们可能会影响构建性能,并使源代码更难以阅读和研究。常规宏难以执行比简单变量替换更复杂的操作,而通过 proc-macro 使用 quote
不允许在文档块中进行变量插值(有关解决方案,请参阅 quote-doctest)。
代码生成也不是完美的。它创建了过多的代码,这些代码很可能是高度重复的,从而产生“噪声”。然而,也很有必要有一个完整的源代码集合,并且可以通过文档轻松访问。由于我们可以在提前生成,它对性能的影响与常规Rust代码相同。
正确的解决方案可能取决于使用场景。我个人认为,宏更适合编写非常简单的重复代码或非常复杂的事情,没有它们就难以完成或不可能完成的事情。代码生成更加专业化,但非常适合生成大量包装代码,尤其是对于每个类型略有不同且需要更多逻辑来处理的代码(特别是在doctests中)。
示例
查看“fibonacci”示例可能最简单: 目录
fib.rs
- 生成的文件flexgen.toml
- 配置文件main.rs
- 生成fib.rs
的源文件
自行运行
- 切换到
examples/basic
目录 - 删除现有的
fib.rs
文件 - 运行:
cargo run --example basic
- 编译新的 fib.rs 文件:
rustc fib.rs -C opt-level=3
- 运行它:
./fib
用法
-
创建一个新的二进制crate(
flexgen
是一个库,不是一个二进制crate) -
编辑
Cargo.toml
并添加任何需要的依赖(至少需要flexgen
,但你可能还需要quote
以及可能的quote-doctest
)
[dependencies]
flexgen = "0.4"
- 编辑你的
main.rs
并添加一个或多个实现CodeFragment
的代码片段。一个片段包含多少代码是一个试错的过程,但通常是一个“一件事”(即一个函数)。有关更多详细信息,请参阅上面的示例。
// main.rs
use flexgen::var::TokenVars;
use flexgen::{import_vars, CodeFragment, Error};
use quote::quote;
struct HelloWorld;
impl CodeFragment for HelloWorld {
fn generate(&self, vars: &TokenVars) -> Result<TokenStream, Error> {
import_vars! { vars => hello };
Ok(quote! {
fn main() {
println!("{hello} world!");
}
})
}
}
- 创建和编辑
flexgen.toml
注意:所有可能的选项都可以在测试代码中找到,请参见 这里
# flexgen.toml
[fragment_lists]
hello = [ "hello_world" ]
[files.hello]
path = "hello.rs"
fragment_list = "hello"
[files.hello.vars]
hello = "Hello"
- 在
main.rs
文件中添加一个main
函数
// main.rs
use flexgen::config::Config;
use flexgen::{register_fragments, Error, CodeGenerator};
fn main() -> Result<(), Error> {
// Register all your code fragments
let fragments = register_fragments!(HelloWorld);
// Read in the configuration from our flexgen.toml file
let config = Config::from_default_toml_file()?;
// Create a new code generator from our fragments and config
let gen = CodeGenerator::new(fragments, config)?;
// Generate our 'hello.rs' file
gen.generate_files()
}
- 执行你的二进制文件以生成代码
cargo run
许可证
此项目可以选择性地根据以下任一许可证进行许可:
- Apache License, Version 2.0, (LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 https://opensource.org/licenses/MIT)
依赖项
~4MB
~75K SLoC