Rust高效数据编码库cdr的使用,支持跨平台序列化与反序列化的二进制数据交换格式
cdr-rs
Rust中通用数据表示的序列化/反序列化实现。
文档
用法
添加到您的Cargo.toml:
[dependencies]
cdr = "0.2.4"
许可证
此项目在以下任一许可下授权
- Apache许可证,版本2.0
- MIT许可证
根据您的选择。
贡献
除非您明确声明,否则任何有意提交用于包含在工作中的贡献,如Apache-2.0许可证中所定义,应如上所述双重许可,无需任何附加条款或条件。
参考
- 通用对象请求代理架构(CORBA)规范,版本3.3,第2部分:CORBA互操作性
完整示例代码:
use cdr::{CdrLe, Infinite};
use serde::{Deserialize, Serialize};
// 定义一个可序列化的结构体
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Point {
x: i32,
y: i32,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建一个Point实例
let point = Point { x: 10, y: 20 };
// 序列化为字节向量
let bytes: Vec<u8> = cdr::serialize::<_, _, CdrLe>(&point, Infinite)?;
println!("Serialized bytes: {:?}", bytes);
// 从字节反序列化
let deserialized: Point = cdr::deserialize::<CdrLe>(&bytes)?;
println!("Deserialized point: {:?}", deserialized);
// 验证数据完整性
assert_eq!(point, deserialized);
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialization() {
let point = Point { x: 42, y: 84 };
let bytes = cdr::serialize::<_, _, CdrLe>(&point, Infinite).unwrap();
let deserialized: Point = cdr::deserialize::<CdrLe>(&bytes).unwrap();
assert_eq!(point, deserialized);
}
}
完整示例demo:
use cdr::{CdrLe, Infinite};
use serde::{Deserialize, Serialize};
// 定义一个可序列化的结构体
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Point {
x: i32,
y: i32,
}
// 定义另一个更复杂的结构体
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Rectangle {
top_left: Point,
bottom_right: Point,
name: String,
visible: bool,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建一个Point实例
let point = Point { x: 10, y: 20 };
// 序列化为字节向量
let bytes: Vec<u8> = cdr::serialize::<_, _, CdrLe>(&point, Infinite)?;
println!("序列化后的字节: {:?}", bytes);
// 从字节反序列化
let deserialized: Point = cdr::deserialize::<CdrLe>(&bytes)?;
println!("反序列化的点: {:?}", deserialized);
// 验证数据完整性
assert_eq!(point, deserialized);
// 复杂结构体示例
let rect = Rectangle {
top_left: Point { x: 0, y: 10 },
bottom_right: Point { x: 20, y: 0 },
name: "My Rectangle".to_string(),
visible: true,
};
// 序列化复杂结构体
let rect_bytes: Vec<u8> = cdr::serialize::<_, _, CdrLe>(&rect, Infinite)?;
println!("矩形序列化字节长度: {}", rect_bytes.len());
// 反序列化复杂结构体
let deserialized_rect: Rectangle = cdr::deserialize::<CdrLe>(&rect_bytes)?;
println!("反序列化的矩形: {:?}", deserialized_rect);
// 验证复杂数据完整性
assert_eq!(rect.name, deserialized_rect.name);
assert_eq!(rect.visible, deserialized_rect.visible);
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_point_serialization() {
let point = Point { x: 42, y: 84 };
let bytes = cdr::serialize::<_, _, CdrLe>(&point, Infinite).unwrap();
let deserialized: Point = cdr::deserialize::<CdrLe>(&bytes).unwrap();
assert_eq!(point, deserialized);
}
#[test]
fn test_rectangle_serialization() {
let rect = Rectangle {
top_left: Point { x: 1, y: 2 },
bottom_right: Point { x: 3, y: 4 },
name: "Test".to_string(),
visible: false,
};
let bytes = cdr::serialize::<_, _, CdrLe>(&rect, Infinite).unwrap();
let deserialized: Rectangle = cdr::deserialize::<CdrLe>(&bytes).unwrap();
assert_eq!(rect.top_left, deserialized.top_left);
assert_eq!(rect.bottom_right, deserialized.bottom_right);
assert_eq!(rect.name, deserialized.name);
assert_eq!(rect.visible, deserialized.visible);
}
}
1 回复
Rust高效数据编码库cdr的使用指南
概述
cdr是一个轻量级、高效的Rust数据编码库,专注于提供跨平台的二进制序列化与反序列化功能。它支持多种数据格式,特别适合需要高性能数据交换的场景。
主要特性
- 零拷贝序列化/反序列化
- 支持大小端字节序
- 跨平台兼容性
- 低内存占用
- 类型安全
安装方法
在Cargo.toml中添加依赖:
[dependencies]
cdr = "0.2"
基本用法示例
1. 基本数据序列化
use cdr::{CdrLe, serialize, deserialize};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 序列化数据
let data = 42u32;
let bytes: Vec<u8> = serialize::<_, CdrLe>(&data)?;
// 反序列化
let decoded: u32 = deserialize::<u32, CdrLe>(&bytes)?;
assert_eq!(data, decoded);
Ok(())
}
2. 结构体序列化
use cdr::{CdrLe, serialize, deserialize};
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Person {
id: u32,
name: String,
age: u8,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let person = Person {
id: 1,
name: "Alice".to_string(),
age: 30,
};
// 序列化结构体
let bytes: Vec<u8> = serialize::<_, CdrLe>(&person)?;
// 反序列化
let decoded: Person = deserialize::<Person, CdrLe>(&bytes)?;
assert_eq!(person, decoded);
Ok(())
}
3. 数组和集合序列化
use cdr::{CdrLe, serialize, deserialize};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 数组序列化
let numbers = vec![1, 2, 3, 4, 5];
let bytes: Vec<u8> = serialize::<_, CdrLe>(&numbers)?;
let decoded: Vec<i32> = deserialize::<Vec<i32>, CdrLe>(&bytes)?;
assert_eq!(numbers, decoded);
Ok(())
}
4. 使用不同字节序
use cdr::{CdrLe, CdrBe, serialize, deserialize};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let data = 0x12345678u32;
// 小端字节序
let le_bytes: Vec<u8> = serialize::<_, CdrLe>(&data)?;
// 大端字节序
let be_bytes: Vec<u8> = serialize::<_, CdrBe>(&data)?;
assert_ne!(le_bytes, be_bytes);
Ok(())
}
高级用法
自定义序列化格式
use cdr::{CdrLe, Infinite, serialize, deserialize};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let data = "Hello, World!";
// 使用无限大小配置
let bytes: Vec<u8> = serialize::<_, CdrLe<Infinite>>(&data)?;
let decoded: String = deserialize::<String, CdrLe<Infinite>>(&bytes)?;
assert_eq!(data, decoded);
Ok(())
}
性能提示
- 对于大型数据集,考虑使用零拷贝技术
- 选择合适的字节序以减少转换开销
- 预分配缓冲区以提高序列化性能
错误处理
use cdr::{CdrLe, serialize, deserialize};
use thiserror::Error;
#[derive(Error, Debug)]
enum MyError {
#[error("Serialization error: {0}")]
Serialization(#[from] cdr::Error),
}
fn process_data() -> Result<(), MyError> {
let data = vec![1, 2, 3];
let bytes = serialize::<_, CdrLe>(&data)?;
let _decoded: Vec<i32> = deserialize::<Vec<i32>, CdrLe>(&bytes)?;
Ok(())
}
注意事项
- 确保序列化和反序列化使用相同的字节序配置
- 注意数据对齐要求
- 处理版本兼容性问题
cdr库提供了简单而强大的二进制数据交换解决方案,特别适合需要高性能和跨平台兼容性的应用场景。
完整示例代码
// 完整示例:使用cdr库进行复杂数据结构的序列化和反序列化
use cdr::{CdrLe, serialize, deserialize};
use serde::{Serialize, Deserialize};
use std::collections::HashMap;
// 定义复杂数据结构
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Employee {
id: u32,
name: String,
department: String,
salary: f64,
skills: Vec<String>,
metadata: HashMap<String, String>,
}
// 嵌套结构体示例
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Company {
name: String,
employees: Vec<Employee>,
founded_year: u32,
active: bool,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建示例数据
let mut employee1 = Employee {
id: 1,
name: "Alice".to_string(),
department: "Engineering".to_string(),
salary: 75000.0,
skills: vec!["Rust".to_string(), "Python".to_string(), "C++".to_string()],
metadata: HashMap::new(),
};
employee1.metadata.insert("level".to_string(), "Senior".to_string());
employee1.metadata.insert("location".to_string(), "Remote".to_string());
let employee2 = Employee {
id: 2,
name: "Bob".to_string(),
department: "Marketing".to_string(),
salary: 65000.0,
skills: vec!["SEO".to_string(), "Content".to_string()],
metadata: HashMap::new(),
};
let company = Company {
name: "TechCorp".to_string(),
employees: vec![employee1, employee2],
founded_year: 2010,
active: true,
};
println!("原始数据: {:?}", company);
// 序列化
let serialized_data: Vec<u8> = serialize::<_, CdrLe>(&company)?;
println!("序列化后的字节数: {}", serialized_data.len());
// 反序列化
let deserialized_company: Company = deserialize::<Company, CdrLe>(&serialized_data)?;
println!("反序列化后的数据: {:?}", deserialized_company);
// 验证数据完整性
assert_eq!(company, deserialized_company);
println!("序列化-反序列化验证成功!");
Ok(())
}
// 性能优化示例:预分配缓冲区和批量处理
use cdr::{CdrLe, serialize, deserialize};
use std::time::Instant;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建大量数据
let large_dataset: Vec<u64> = (0..1_000_000).collect();
// 性能测试:普通序列化
let start = Instant::now();
let serialized = serialize::<_, CdrLe>(&large_dataset)?;
let duration = start.elapsed();
println!("普通序列化耗时: {:?}", duration);
// 性能测试:预分配缓冲区
let start = Instant::now();
let mut buffer = Vec::with_capacity(8_000_000); // 预分配足够空间
cdr::serialize_into::<_, CdrLe>(&mut buffer, &large_dataset)?;
let duration = start.elapsed();
println!("预分配缓冲区序列化耗时: {:?}", duration);
// 反序列化性能测试
let start = Instant::now();
let deserialized: Vec<u64> = deserialize::<Vec<u64>, CdrLe>(&buffer)?;
let duration = start.elapsed();
println!("反序列化耗时: {:?}", duration);
assert_eq!(large_dataset, deserialized);
println!("批量数据处理验证成功!");
Ok(())
}
// 错误处理和自定义配置示例
use cdr::{CdrLe, CdrBe, Infinite, Bounded, serialize, deserialize};
use thiserror::Error;
use std::io::Cursor;
#[derive(Error, Debug)]
enum ApplicationError {
#[error("CDR序列化错误: {0}")]
CdrSerialization(#[from] cdr::Error),
#[error("数据验证失败")]
ValidationError,
#[error("缓冲区大小不足")]
BufferTooSmall,
}
// 使用不同配置的序列化示例
fn advanced_serialization() -> Result<(), ApplicationError> {
let data = "这是一个较长的测试字符串,用于演示不同配置的效果";
// 使用无限大小配置
let infinite_bytes = serialize::<_, CdrLe<Infinite>>(&data)?;
// 使用有限大小配置(可能失败)
let bounded_result = serialize::<_, CdrLe<Bounded<100>>>(&data);
if bounded_result.is_err() {
println!("有限大小配置序列化失败(预期中)");
}
// 使用大端字节序
let be_bytes = serialize::<_, CdrBe<Infinite>>(&data)?;
// 验证不同配置的结果
println!("小端字节序数据长度: {}", infinite_bytes.len());
println!("大端字节序数据长度: {}", be_bytes.len());
// 从字节流反序列化
let mut cursor = Cursor::new(infinite_bytes);
let decoded: String = cdr::deserialize_from::<_, CdrLe<Infinite>>(&mut cursor)?;
if decoded == data {
println!("自定义配置序列化/反序列化成功!");
Ok(())
} else {
Err(ApplicationError::ValidationError)
}
}
fn main() -> Result<(), ApplicationError> {
advanced_serialization()?;
Ok(())
}