Rust代码生成与自动化工具库codes-agency的使用,高效实现Rust项目自动化与代码管理

Rust代码生成与自动化工具库codes-agency的使用,高效实现Rust项目自动化与代码管理

Crate codes-agency

这个包提供了表示标准机构的通用代码。

crates.io docs.rs

两个核心类型[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

  1. 从agencies.xml创建一个构建系统
  2. 添加一个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!");
}

这个增强版示例展示了如何:

  1. 创建多个不同类型的标准定义
  2. 使用辅助函数减少重复代码
  3. 批量验证标准信息
  4. 处理可能为空的long_ref字段
  5. 在实际项目中组织和管理多个标准

您可以根据需要扩展这个示例,例如:

  • 添加更多标准机构
  • 实现标准分类系统
  • 创建自动化工具来生成标准文档
  • 将标准信息导出为不同格式

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!("项目初始化和代码生成完成!");
}

补充说明

  1. 模板文件的使用:可以将模板存储在单独的文件中,例如templates/model.tpl,然后读取使用:
let template = std::fs::read_to_string("templates/model.tpl")?;
let mut generator = CodeGenerator::new(&template);
  1. 条件生成:可以根据条件决定是否生成某些代码:
generator.set_condition("has_serialize", true);
// 在模板中使用 {{#if has_serialize}}...{{/if}}
  1. 循环生成:对于需要重复生成的结构,可以使用循环:
let fields = vec!["id: u64", "name: String"];
generator.set_array("fields", fields);
// 在模板中使用 {{#each fields}}{{this}}{{/each}}
回到顶部