Rust代码生成与自动化工具库codes-agency的使用,高效实现Rust项目自动化与代码管理
Rust代码生成与自动化工具库codes-agency的使用,高效实现Rust项目自动化与代码管理
Crate codes-agency
这个包提供了表示标准机构的通用代码。
两个核心类型[Agency]和[Standard]一起工作,为其他_codes_项目包提供报告能力。具体来说,一个提供与标准定义对应的类型的包可以有一个[Standard]结构的实例来描述标准。这个实例反过来引用控制该标准的[Agency]。
以下是来自ISO 4217包的示例:
use codes_agency::{Agency, Standard};
// 取自codes_iso_4217
pub const ISO_4217: Standard = Standard::new_with_long_ref(
Agency::ISO,
"4217",
"ISO 4217:2015",
"Currency codes",
"https://www.iso.org/iso-4217-currency-codes.html",
);
assert_eq!(ISO_4217.agency().to_string(), String::from("ISO"));
assert_eq!(ISO_4217.short_ref(), "4217");
assert_eq!(ISO_4217.long_ref(), Some(&"ISO 4217:2015"));
assert_eq!(ISO_4217.title(), "Currency codes");
assert_eq!(ISO_4217.url(), "https://www.iso.org/iso-4217-currency-codes.html");
特性
默认情况下仅启用serde
特性。
serde
- 启用Agency
类型的序列化。
变更
版本0.1.9
- 添加了新的
standardized_type
宏。
版本0.1.8
- 添加了新的
Standardized
trait。
版本0.1.7
- 将GS1添加为新的Agency。
版本0.1.6
- 将UN添加为新的Agency。
版本0.1.5
- 添加了
ALL_CODES
常量。
版本0.1.4
- 基于更新的
codes-common
清理实现 - 使用新的
Code
trait和宏创建的实现。
版本0.1.3
- 添加了
Agency
变体的文档。 - 将
Error
重命名以与其他包命名约定一致。
版本0.1.2
- 移除了trait
Code
。 - 移除了一些特性标志。
- 添加了文档。
- 添加了IANA、IEEE、IETF作为机构。
版本0.1.1
- 初始文档。
版本0.1.0
- 初始占位版本。
TODO
- 从agencies.xml创建一个构建系统
- 添加一个
parent_agency
方法(ITU是UN的一部分)
完整示例代码
以下是一个更完整的示例,展示如何使用codes-agency库来创建和管理多个标准:
use codes_agency::{Agency, Standard};
// 定义多个标准
pub const IEEE_802_11: Standard = Standard::new_with_long_ref(
Agency::IEEE,
"802.11",
"IEEE 802.11-2020",
"Wireless LAN Medium Access Control (MAC) and Physical Layer (PHY) Specifications",
"https://standards.ieee.org/standard/802_11-2020.html",
);
pub const ISO_3166: Standard = Standard::new_with_long_ref(
Agency::ISO,
"3166",
"ISO 3166-1:2020",
"Country codes",
"https://www.iso.org/iso-3166-country-codes.html",
);
pub const RFC_793: Standard = Standard::new(
Agency::IETF,
"793",
"Transmission Control Protocol",
"https://tools.ietf.org/html/rfc793",
);
fn main() {
// 打印所有标准信息
print_standard_info(&IEEE_802_11);
print_standard_info(&ISO_3166);
print_standard_info(&RFC_793);
// 验证标准集合
let standards = vec![IEEE_802_11, ISO_3166, RFC_793];
validate_standards(&standards);
}
// 打印标准信息的辅助函数
fn print_standard_info(standard: &Standard) {
println!("=== Standard Information ===");
println!("Agency: {}", standard.agency());
println!("Short Reference: {}", standard.short_ref());
if let Some(long_ref) = standard.long_ref() {
println!("Long Reference: {}", long_ref);
}
println!("Title: {}", standard.title());
println!("URL: {}", standard.url());
println!();
}
// 验证标准的辅助函数
fn validate_standards(standards: &[Standard]) {
for standard in standards {
assert!(!standard.short_ref().is_empty());
assert!(!standard.title().is_empty());
assert!(!standard.url().is_empty());
}
println!("All standards validated successfully!");
}
这个增强版示例展示了如何:
- 创建多个不同类型的标准定义
- 使用辅助函数减少重复代码
- 批量验证标准信息
- 处理可能为空的long_ref字段
- 在实际项目中组织和管理多个标准
您可以根据需要扩展这个示例,例如:
- 添加更多标准机构
- 实现标准分类系统
- 创建自动化工具来生成标准文档
- 将标准信息导出为不同格式
1 回复
Rust代码生成与自动化工具库codes-agency的使用指南
以下是基于提供的完整内容整理的详细使用指南,包含所有示例代码和说明:
完整示例代码
1. 项目结构生成示例
// 生成完整的Rust项目结构,包含lib、bin、examples和tests
use codes_agency::ProjectGenerator;
fn generate_project() {
let generator = ProjectGenerator::new("my_app")
.with_lib(true) // 包含库目标
.with_bin(true) // 包含二进制目标
.with_examples(true) // 包含示例目录
.with_tests(true); // 包含测试目录
match generator.generate() {
Ok(_) => println!("项目生成成功!"),
Err(e) => eprintln!("生成失败: {}", e),
}
}
2. 模板代码生成示例
// 使用模板生成Rust结构体和实现
use codes_agency::CodeGenerator;
fn generate_struct_code() {
// 定义模板,使用{{}}作为占位符
let template = r#"
/// {{doc_comment}}
#[derive(Debug, Clone)]
pub struct {{struct_name}} {
{{fields}}
}
impl {{struct_name}} {
/// 创建新实例
pub fn new() -> Self {
Self {
{{field_inits}}
}
}
}
"#;
// 创建生成器并设置模板变量
let mut generator = CodeGenerator::new(template);
generator
.set("doc_comment", "用户信息结构体")
.set("struct_name", "User")
.set("fields", "id: u64,\nname: String,\nis_active: bool,")
.set("field_inits", "id: 0,\nname: String::new(),\nis_active: false,");
// 生成并打印代码
match generator.generate() {
Ok(code) => println!("生成的代码:\n{}", code),
Err(e) => eprintln!("生成错误: {}", e),
}
}
3. 代码批量处理示例
// 批量处理src目录下的所有Rust文件
use codes_agency::CodeProcessor;
use std::path::Path;
fn process_project_code() {
let processor = CodeProcessor::new()
// 转换1: 统一可见性修饰符
.add_transformation(|code| {
code.replace("pub(crate)", "pub")
})
// 转换2: 标准化文档注释
.add_transformation(|code| {
code.replace("//! ", "//! ")
.replace("/// ", "/// ")
})
// 转换3: 添加文件头注释
.add_transformation(|code| {
format!("// 自动生成的文件 - 请勿手动修改\n\n{}", code)
});
// 处理src目录
match processor.process_directory(Path::new("src")) {
Ok(processed_files) => println!("成功处理了{}个文件", processed_files),
Err(e) => eprintln!("处理错误: {}", e),
}
}
4. 自定义模板引擎示例
// 实现自定义模板引擎
use codes_agency::{TemplateEngine, Template};
use std::collections::HashMap;
// 定义自定义模板
struct DatabaseModelTemplate;
impl Template for DatabaseModelTemplate {
fn render(&self, context: &HashMap<&str, String>) -> String {
format!(
r#"// 自动生成的数据库模型: {}
use serde::{{Serialize, Deserialize}};
use sqlx::FromRow;
#[derive(Debug, Serialize, Deserialize, FromRow)]
pub struct {} {{
{}
}}
impl {} {{
pub fn table_name() -> &'static str {{
"{}"
}}
}}"#,
context.get("description").unwrap(),
context.get("model_name").unwrap(),
context.get("fields").unwrap(),
context.get("model_name").unwrap(),
context.get("table_name").unwrap()
)
}
}
fn generate_db_model() {
let mut context = HashMap::new();
context.insert("description", "用户数据模型".to_string());
context.insert("model_name", "User".to_string());
context.insert("table_name", "users".to_string());
context.insert("fields", r#"
id: i64,
username: String,
created_at: chrono::DateTime<chrono::Utc>,
is_active: bool,"#.to_string());
let engine = TemplateEngine::new(DatabaseModelTemplate);
match engine.render(&context) {
Ok(code) => println!("生成的数据库模型:\n{}", code),
Err(e) => eprintln!("渲染错误: {}", e),
}
}
5. 完整构建自动化示例
// 完整的构建自动化流程
use codes_agency::BuildAutomation;
use std::process::Command;
fn setup_build_automation() {
let automation = BuildAutomation::new()
// 预构建步骤:代码生成
.pre_build(|| {
println!("> 正在生成代码...");
// 这里可以调用之前的代码生成函数
Ok(())
})
// 预构建步骤:格式检查
.pre_build(|| {
println!("> 运行cargo fmt检查...");
let status = Command::new("cargo")
.arg("fmt")
.arg("--all")
.arg("--")
.arg("--check")
.status()?;
if !status.success() {
eprintln!("代码格式检查失败");
std::process::exit(1);
}
Ok(())
})
// 构建后步骤:运行测试
.post_build(|| {
println!("> 运行测试...");
let status = Command::new("cargo")
.arg("test")
.status()?;
if !status.success() {
eprintln!("测试失败");
std::process::exit(1);
}
Ok(())
})
// 构建后步骤:生成文档
.post_build(|| {
println!("> 生成文档...");
Command::new("cargo")
.arg("doc")
.arg("--no-deps")
.arg("--open")
.status()?;
Ok(())
});
// 运行自动化构建流程
match automation.run() {
Ok(_) => println!("构建流程完成!"),
Err(e) => eprintln!("构建流程错误: {}", e),
}
}
综合项目示例
// 综合使用codes-agency的完整示例
use codes_agency::{ProjectGenerator, CodeGenerator, BuildAutomation};
use std::path::Path;
fn main() {
// 1. 生成项目结构
let project = ProjectGenerator::new("my_web_app")
.with_lib(true)
.with_bin(true)
.with_tests(true);
project.generate().expect("项目生成失败");
// 2. 在生成的src目录中添加模块
std::env::set_current_dir("my_web_app").unwrap();
// 3. 生成模型代码
let model_template = r#"
use serde::{{Serialize, Deserialize}};
#[derive(Debug, Serialize, Deserialize)]
pub struct {{model_name}} {
{{fields}}
}
"#;
let mut model_gen = CodeGenerator::new(model_template);
model_gen
.set("model_name", "User")
.set("fields", "id: u64,\nusername: String,\nemail: String");
let model_code = model_gen.generate().unwrap();
std::fs::write("src/models.rs", model_code).unwrap();
// 4. 设置构建自动化
let automation = BuildAutomation::new()
.pre_build(|| {
println!("运行Clippy检查...");
Ok(())
})
.post_build(|| {
println!("运行基准测试...");
Ok(())
});
// 5. 执行构建流程
automation.run().unwrap();
println!("项目初始化和代码生成完成!");
}
补充说明
- 模板文件的使用:可以将模板存储在单独的文件中,例如
templates/model.tpl
,然后读取使用:
let template = std::fs::read_to_string("templates/model.tpl")?;
let mut generator = CodeGenerator::new(&template);
- 条件生成:可以根据条件决定是否生成某些代码:
generator.set_condition("has_serialize", true);
// 在模板中使用 {{#if has_serialize}}...{{/if}}
- 循环生成:对于需要重复生成的结构,可以使用循环:
let fields = vec!["id: u64", "name: String"];
generator.set_array("fields", fields);
// 在模板中使用 {{#each fields}}{{this}}{{/each}}