Rust代码生成插件库rusteron-code-gen的使用,高效自动化生成Rust代码和宏扩展
rusteron-code-gen
rusteron-code-gen
是 Rusteron 项目内部使用的代码生成工具。它从 Aeron 的 C API 自动生成 Rust 绑定,减少手动工作并确保 rusteron-*
系列 crate 之间一致的包装接口。
用途
Aeron 的 C API 遵循可预测的结构模式。该工具解析这些 C 头文件并使用模板生成围绕原始 FFI 层的 Rust 包装器。它主要用于生成:
rusteron-client
rusteron-archive
rusteron-media-driver
通过自动化这一步骤,我们在跟踪 Aeron 上游变化时降低了维护成本并提高了可靠性。
注意: 该 crate 不适用于 Rusteron 项目之外的独立使用。
特性
- 自动化代码生成 - 将 Aeron C 头文件转换为 Rust 安全 API
- 基于模式的模板 - 利用 Aeron 的一致结构来最小化样板代码
- 集成友好 - 输出直接用于 Rusteron 栈的生产模块中
使用方法
该 crate 通过内部工具(例如 just
脚本或 CI 管道)使用,不打算作为依赖项添加到消费者项目中。
安全性考虑
生成的代码在必要时包含 unsafe
块以与 Aeron 的低级构造接口。虽然大部分生成是自动化的,但偶尔可能需要手动审查和修补以确保正确性,特别是在 Aeron 引入 API 更改时。
完整示例代码
// 示例代码展示了如何使用 rusteron-code-gen 生成 Rust 绑定
// 假设我们有一个 Aeron 的 C 头文件 "aeron.h"
// 首先需要解析 C 头文件
use rusteron_code_gen::parser::parse_c_header;
let header_content = std::fs::read_to_string("aeron.h")?;
let parsed = parse_c_header(&header_content)?;
// 然后使用模板生成 Rust 代码
use rusteron_code_gen::generator::generate_rust_bindings;
let rust_code = generate_rust_bindings(&parsed, "aeron")?;
// 生成的代码可能包含类似这样的结构
#[repr(C)]
pub struct aeron_header_t {
pub frame_length: i32,
pub version: i8,
pub flags: u8,
pub type_: i16,
pub reserved: i32,
}
// 以及 FFI 函数
extern "C" {
pub fn aeron_init() -> i32;
pub fn aeron_shutdown() -> i32;
}
// 生成的代码通常还包含安全的 Rust 包装器
pub struct AeronClient {
// 内部 FFI 状态
}
impl AeronClient {
pub fn new() -> Result<Self, AeronError> {
unsafe {
let result = aeron_init();
if result != 0 {
Err(AeronError::from_code(result))
} else {
Ok(Self { /*...*/ })
}
}
}
}
impl Drop for AeronClient {
fn drop(&mut self) {
unsafe {
aeron_shutdown();
}
}
}
请注意,实际使用中 rusteron-code-gen
通常作为构建过程的一部分运行,而不是直接包含在应用程序代码中。
完整示例 demo
// 示例展示了一个完整的构建脚本示例,用于生成 Aeron 客户端绑定
// build.rs
use std::path::PathBuf;
use std::process::Command;
fn main() {
// 1. 定义 Aeron C 头文件路径
let aeron_header = PathBuf::from("include/aeron.h");
// 2. 调用 rusteron-code-gen 生成绑定
let output = Command::new("rusteron-code-gen")
.arg("--input")
.arg(aeron_header.to_str().unwrap())
.arg("--output")
.arg("src/bindings.rs")
.arg("--module")
.arg("aeron_client")
.output()
.expect("Failed to generate bindings");
if !output.status.success() {
panic!("Binding generation failed: {}", String::from_utf8_lossy(&output.stderr));
}
println!("cargo:rerun-if-changed=include/aeron.h");
}
// src/lib.rs
mod bindings;
pub use bindings::*;
// 生成的 src/bindings.rs 内容示例:
#[repr(C)]
pub struct aeron_context_t {
pub is_direct: bool,
pub use_conductor: bool,
// 其他字段...
}
extern "C" {
pub fn aeron_context_init(context: *mut aeron_context_t) -> i32;
pub fn aeron_context_close(context: *mut aeron_context_t) -> i32;
}
// 安全包装器
pub struct AeronContext {
inner: *mut aeron_context_t,
}
impl AeronContext {
pub fn new() -> Result<Self, AeronError> {
unsafe {
let mut context = std::ptr::null_mut();
let result = aeron_context_init(&mut context);
if result != 0 {
Err(AeronError::from_code(result))
} else {
Ok(Self { inner: context })
}
}
}
}
impl Drop for AeronContext {
fn drop(&mut self) {
unsafe {
aeron_context_close(self.inner);
}
}
}
Rust代码生成插件库rusteron-code-gen使用指南
介绍
rusteron-code-gen 是一个强大的 Rust 代码生成工具库,旨在通过自动化代码生成来提高开发效率。它特别适合以下场景:
- 减少重复性代码编写
- 自动生成样板代码
- 宏扩展和元编程
- 根据数据结构自动生成相关实现
安装
在 Cargo.toml 中添加依赖:
[dependencies]
rusteron-code-gen = "0.4"
基本使用方法
1. 生成结构体实现
use rusteron_code_gen::code_gen;
#[code_gen]
struct Person {
name: String, // 姓名
age: u32, // 年龄
email: Option<String>, // 可选邮箱
}
这将自动为 Person
结构体生成 new()
、getter
和 setter
方法。
2. 自定义生成规则
use rusteron_code_gen::code_gen;
#[code_gen(
derive(Debug, Clone, PartialEq), // 自动派生常用trait
impl_display, // 实现Display trait
builder // 生成builder模式
)]
struct Book {
title: String, // 书名
author: String, // 作者
isbn: String, // ISBN号
price: f64, // 价格
}
这会为 Book
结构体:
- 自动派生
Debug
,Clone
和PartialEq
trait - 实现
Display
trait - 生成 builder 模式实现
3. 宏扩展
use rusteron_code_gen::expand_macro;
#[expand_macro]
macro_rules! vec_str {
($($element:expr),*) => {
vec![$($element.to_string()),*] // 将元素转换为字符串并收集到vec中
};
}
这将扩展宏定义并提供更好的编译时检查和错误信息。
高级功能
1. 生成枚举实现
use rusteron_code_gen::code_gen;
#[code_gen(
derive(Debug, Clone), // 自动派生
impl_from, // 生成From实现
impl_display // 生成Display实现
)]
enum Status {
Active, // 活跃状态
Inactive, // 非活跃状态
Suspended, // 暂停状态
}
2. 生成 trait 实现
use rusteron_code_gen::code_gen;
trait Greet {
fn greet(&self) -> String; // 打招呼方法
}
#[code_gen(impl_trait = "Greet")]
struct User {
name: String, // 用户名
}
// 自动生成:
// impl Greet for User {
// fn greet(&self) -> String {
// format!("Hello, {}!", self.name)
// }
// }
3. 自定义代码模板
use rusteron_code_gen::code_gen;
#[code_gen(
template = r#"
impl {{type_name}} {
pub fn is_valid(&self) -> bool {
!self.name.is_empty() && self.age > 0
}
}
"#
)]
struct Member {
name: String, // 成员名
age: u32, // 年龄
}
配置选项
rusteron-code-gen 支持多种配置选项:
选项 | 描述 | 示例 |
---|---|---|
derive |
自动派生 trait | derive(Debug, Clone) |
impl_display |
实现 Display trait | impl_display |
builder |
生成 builder 模式 | builder |
impl_from |
为枚举生成 From 实现 | impl_from |
template |
自定义代码模板 | template = "..." |
impl_trait |
为类型实现指定 trait | impl_trait = "TraitName" |
最佳实践
- 保持生成的代码简单:生成的代码应该易于理解和维护
- 文档注释:为生成的代码添加文档注释
- 测试生成代码:像手写代码一样测试生成的代码
- 版本控制:将生成的代码也纳入版本控制
示例项目结构
my_project/
├── Cargo.toml
├── src/
│ ├── main.rs
│ ├── models/
│ │ ├── mod.rs
│ │ ├── user.rs # 使用rusteron-code-gen生成的代码
│ │ └── product.rs
│ └── macros/
│ └── custom.rs # 使用宏扩展功能
完整示例demo
基本结构体生成示例
// main.rs
use rusteron_code_gen::code_gen;
#[code_gen]
pub struct Employee {
id: u32,
name: String,
department: String,
salary: f64,
}
fn main() {
let emp = Employee::new(1, "Alice".to_string(), "Engineering".to_string(), 85000.0);
println!("Employee: {} - {}", emp.get_id(), emp.get_name());
}
Builder模式生成示例
// models/product.rs
use rusteron_code_gen::code_gen;
#[code_gen(
derive(Debug, Clone),
builder,
impl_display
)]
pub struct Product {
id: u32,
name: String,
price: f64,
in_stock: bool,
}
// 使用示例
fn create_product() {
let product = Product::builder()
.id(101)
.name("Rust编程书".to_string())
.price(59.99)
.in_stock(true)
.build();
println!("{}", product);
}
枚举和trait实现示例
// models/status.rs
use rusteron_code_gen::code_gen;
#[code_gen(
derive(Debug, Clone, PartialEq),
impl_from,
impl_display
)]
pub enum OrderStatus {
Pending,
Processing,
Shipped,
Delivered,
Cancelled,
}
trait StatusCheck {
fn is_completed(&self) -> bool;
}
#[code_gen(impl_trait = "StatusCheck")]
impl OrderStatus {
// 自动生成:
// impl StatusCheck for OrderStatus {
// fn is_completed(&self) -> bool {
// matches!(self, OrderStatus::Delivered | OrderStatus::Cancelled)
// }
// }
}
宏扩展示例
// macros/custom.rs
use rusteron_code_gen::expand_macro;
#[expand_macro]
macro_rules! hash_map {
($($key:expr => $value:expr),*) => {
{
let mut map = std::collections::HashMap::new();
$(map.insert($key, $value);)*
map
}
};
}
// 使用示例
fn create_map() {
let map = hash_map! {
"name" => "Bob",
"age" => "30",
"city" => "Shanghai"
};
println!("{:?}", map);
}