Rust版本控制与代码生成库revision-derive的使用:简化版本管理并自动化生成修订代码
revision-derive
revision的过程宏私有实现。
元数据
包标识符: pkg:cargo/revision-derive@0.12.0
更新时间: 3个月前
版本: 2021 edition
许可证: Apache-2.0
大小: 15.8 KiB
安装
在项目目录中运行以下Cargo命令:
cargo add revision-derive
或者在Cargo.toml中添加以下行:
revision-derive = "0.12.0"
文档
docs.rs/revision-derive/0.12.0
仓库
所有者
- Tobie Morgan Hitchcock
分类
- Encoding
完整示例代码
use revision::revision;
use revision_derive::Revision;
use serde::{Deserialize, Serialize};
// 定义一个带有版本控制的结构体
#[derive(Debug, Clone, Serialize, Deserialize, Revision)]
#[revision = "v1"] // 初始版本
struct User {
id: u64,
name: String,
email: String,
}
impl User {
// 创建新用户
fn new(id: u64, name: String, email: String) -> Self {
Self { id, name, email }
}
}
fn main() {
// 创建用户实例
let user = User::new(1, "Alice".to_string(), "alice@example.com".to_string());
println!("User: {:?}", user);
println!("Revision: {}", user.revision());
// 序列化示例
let serialized = serde_json::to_string(&user).unwrap();
println!("Serialized: {}", serialized);
// 反序列化示例
let deserialized: User = serde_json::from_str(&serialized).unwrap();
println!("Deserialized: {:?}", deserialized);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_user_creation() {
let user = User::new(1, "Test".to_string(), "test@example.com".to_string());
assert_eq!(user.id, 1);
assert_eq!(user.name, "Test");
assert_eq!(user.email, "test@example.com");
}
#[test]
fn test_revision() {
let user = User::new(1, "Test".to_string(), "test@example.com".to_string());
assert_eq!(user.revision(), "v1");
}
}
Cargo.toml 依赖配置:
[dependencies]
revision = "0.12.0"
revision-derive = "0.12.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
1 回复
Rust版本控制与代码生成库revision-derive使用指南
概述
revision-derive是一个用于简化Rust代码版本管理的派生宏库,通过自动化生成修订代码来帮助开发者管理数据结构的不同版本。
主要功能
- 自动生成版本控制相关代码
- 支持数据结构的多版本序列化/反序列化
- 提供版本迁移和兼容性处理
安装方法
在Cargo.toml中添加依赖:
[dependencies]
revision-derive = "0.1"
serde = { version = "1.0", features = ["derive"] }
基本用法示例
use revision_derive::Revisioned;
use serde::{Deserialize, Serialize};
#[derive(Revisioned, Serialize, Deserialize, Debug)]
#[revision(version = 1)]
struct User {
id: u64,
name: String,
#[revision(version = 2)]
email: Option<String>,
#[revision(version = 3)]
age: u32,
}
fn main() {
// 自动生成的版本信息
println!("Current version: {}", User::current_version());
// 序列化示例
let user = User {
id: 1,
name: "Alice".to_string(),
email: Some("alice@example.com".to_string()),
age: 25,
};
let bytes = user.to_bytes().unwrap();
// 反序列化示例(自动处理版本兼容)
let decoded: User = User::from_bytes(&bytes).unwrap();
println!("Decoded user: {:?}", decoded);
}
高级功能
自定义版本迁移
#[derive(Revisioned)]
#[revision(version = 2)]
struct Product {
name: String,
#[revision(version = 1, rename = "old_price")]
price: f64,
#[revision(version = 2)]
category: String,
#[revision_migration(from = 1)]
fn migrate_v1_to_v2(old: &[u8]) -> Result<Self, RevisionError> {
// 自定义迁移逻辑
Ok(Product {
name: "Migrated".to_string(),
price: 0.0,
category: "Default".to_string(),
})
}
}
版本范围支持
#[derive(Revisioned)]
struct Config {
#[revision(start = 1, end = 3)]
old_setting: String,
#[revision(start = 2)]
new_setting: i32,
}
特性说明
- 自动版本检测:根据字段注解自动确定数据结构版本
- 向后兼容:支持旧版本数据的自动转换
- 灵活配置:支持版本范围、重命名等高级功能
- 错误处理:提供详细的版本迁移错误信息
注意事项
- 确保所有修订版本的字段都有合理的默认值或迁移逻辑
- 版本号应该单调递增
- 测试所有版本迁移路径以确保兼容性
这个库特别适合需要长期维护和演进的数据结构,特别是在需要保持向后兼容性的分布式系统或持久化存储场景中。
完整示例demo
use revision_derive::Revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
// 定义错误类型
#[derive(Debug)]
pub enum RevisionError {
MigrationError(String),
SerializationError(String),
DeserializationError(String),
}
impl fmt::Display for RevisionError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
RevisionError::MigrationError(msg) => write!(f, "Migration error: {}", msg),
RevisionError::SerializationError(msg) => write!(f, "Serialization error: {}", msg),
RevisionError::DeserializationError(msg) => write!(f, "Deserialization error: {}", msg),
}
}
}
impl std::error::Error for RevisionError {}
// 用户数据结构示例
#[derive(Revisioned, Serialize, Deserialize, Debug, PartialEq)]
#[revision(version = 1)]
struct User {
id: u64, // 从版本1开始存在
name: String, // 从版本1开始存在
#[revision(version = 2)] // 从版本2开始添加
email: Option<String>,
#[revision(version = 3)] // 从版本3开始添加
age: u32,
}
// 产品数据结构示例(带自定义迁移)
#[derive(Revisioned, Debug, PartialEq)]
#[revision(version = 2)]
struct Product {
name: String,
#[revision(version = 1, rename = "old_price")] // 版本1中名为old_price
price: f64,
#[revision(version = 2)] // 从版本2开始添加
category: String,
#[revision_migration(from = 1)]
fn migrate_v1_to_v2(old_data: &[u8]) -> Result<Self, RevisionError> {
// 模拟从版本1迁移到版本2的逻辑
// 在实际应用中,这里会解析旧版本数据并转换为新版本
println!("Migrating from version 1 to version 2...");
Ok(Product {
name: "Migrated Product".to_string(),
price: 99.99,
category: "Electronics".to_string(),
})
}
}
// 配置数据结构示例(版本范围支持)
#[derive(Revisioned, Debug, PartialEq)]
struct Config {
#[revision(start = 1, end = 3)] // 只在版本1-3中存在
old_setting: String,
#[revision(start = 2)] // 从版本2开始存在
new_setting: i32,
}
fn main() -> Result<(), RevisionError> {
println!("=== User 示例 ===");
// 创建用户实例
let user = User {
id: 1,
name: "Alice".to_string(),
email: Some("alice@example.com".to_string()),
age: 25,
};
// 显示当前版本
println!("Current User version: {}", User::current_version());
println!("Original user: {:?}", user);
// 序列化
let bytes = user.to_bytes().map_err(|e| RevisionError::SerializationError(e.to_string()))?;
println!("Serialized bytes length: {}", bytes.len());
// 反序列化
let decoded: User = User::from_bytes(&bytes).map_err(|e| RevisionError::DeserializationError(e.to_string()))?;
println!("Decoded user: {:?}", decoded);
println!("Users are equal: {}", user == decoded);
println!("\n=== Product 示例 ===");
// 产品示例
let product = Product {
name: "Laptop".to_string(),
price: 1299.99,
category: "Computers".to_string(),
};
println!("Current Product version: {}", Product::current_version());
println!("Product: {:?}", product);
println!("\n=== Config 示例 ===");
// 配置示例
let config = Config {
old_setting: "old_value".to_string(),
new_setting: 42,
};
println!("Config: {:?}", config);
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_user_serialization() {
let user = User {
id: 1,
name: "Test".to_string(),
email: Some("test@example.com".to_string()),
age: 30,
};
let bytes = user.to_bytes().unwrap();
let decoded: User = User::from_bytes(&bytes).unwrap();
assert_eq!(user, decoded);
}
#[test]
fn test_version_info() {
assert_eq!(User::current_version(), 3);
assert_eq!(Product::current_version(), 2);
}
}
这个完整示例展示了revision-derive库的主要功能:
- 基本用法:User结构体展示了版本控制的基本用法,包含不同版本添加的字段
- 自定义迁移:Product结构体演示了如何实现自定义版本迁移逻辑
- 版本范围:Config结构体展示了版本范围的使用
- 错误处理:包含了完整的错误处理机制
- 测试用例:提供了基本的测试示例
要运行此示例,请确保在Cargo.toml中添加了正确的依赖项,并根据需要调整版本号。