Rust序列化与反序列化库nanoserde-derive的使用,轻量级零依赖的编译时derive宏工具

// 在Cargo.toml中添加依赖
// nanoserde-derive = "0.2.1"

use nanoserde_derive::{DeBin, SerBin};

#[derive(DeBin, SerBin)]
struct MyStruct {
    number: i32,
    string: String,
    vector: Vec<u8>,
}

fn main() {
    // 序列化示例
    let test = MyStruct {
        number: 42,
        string: "hello world".to_string(),
        vector: vec![1, 2, 3],
    };
    
    // 将结构体序列化为二进制数据
    let bytes = SerBin::serialize_bin(&test);
    
    // 反序列化示例
    // 从二进制数据反序列化为结构体
    let test_deserialized: MyStruct = DeBin::deserialize_bin(&bytes).unwrap();
    
    println!("原始数字: {}", test.number);
    println!("反序列化后的数字: {}", test_deserialized.number);
    println!("原始字符串: {}", test.string);
    println!("反序列化后的字符串: {}", test_deserialized.string);
}

nanoserde-derive是一个轻量级的零依赖序列化库,专门为Rust语言设计。它通过编译时derive宏提供简单的序列化和反序列化功能。

主要特性:

  • 零依赖:不依赖任何其他库,保持轻量级
  • 编译时宏:使用derive宏自动生成序列化代码
  • 支持基本类型:包括i32、String、Vec等常见类型
  • 二进制格式:专注于二进制序列化格式

安装方式: 在Cargo.toml中添加依赖:nanoserde-derive = “0.2.1”

使用示例: 通过derive宏为结构体自动实现SerBin和DeBin trait,即可获得序列化和反序列化能力。序列化后的数据为二进制格式,适合网络传输或文件存储。

该库特别适合需要轻量级序列化解决方案的场景,避免了引入大型序列化框架的开销。

完整示例demo:

// 在Cargo.toml中添加依赖
// nanoserde-derive = "0.2.1"

use nanoserde_derive::{DeBin, SerBin};

// 定义需要序列化的结构体
#[derive(DeBin, SerBin, Debug)]
struct MyStruct {
    number: i32,           // 整数字段
    string: String,        // 字符串字段
    vector: Vec<u8>,       // 字节向量字段
}

fn main() {
    // 创建结构体实例
    let original = MyStruct {
        number: 42,
        string: "hello world".to_string(),
        vector: vec![1, 2, 3, 4, 5],
    };

    println!("原始结构体: {:?}", original);
    
    // 序列化为二进制数据
    let serialized_bytes = SerBin::serialize_bin(&original);
    println!("序列化后的字节数: {}", serialized_bytes.len());
    
    // 反序列化回结构体
    let deserialized: MyStruct = DeBin::deserialize_bin(&serialized_bytes).unwrap();
    
    // 验证数据完整性
    println!("反序列化后的结构体: {:?}", deserialized);
    println!("数字字段匹配: {}", original.number == deserialized.number);
    println!("字符串字段匹配: {}", original.string == deserialized.string);
    println!("向量字段匹配: {}", original.vector == deserialized.vector);
    
    // 演示错误处理
    let invalid_bytes = vec![0u8; 10];
    match DeBin::deserialize_bin::<MyStruct>(&invalid_bytes) {
        Ok(_) => println!("反序列化成功"),
        Err(e) => println!("反序列化失败: {}", e),
    }
}

1 回复

Rust序列化与反序列化库nanoserde-derive使用指南

概述

nanoserde-derive是一个轻量级、零依赖的Rust序列化与反序列化库,通过编译时derive宏提供高效的二进制和JSON格式支持。

主要特性

  • 零运行时依赖
  • 编译时derive宏实现
  • 支持二进制和JSON格式
  • 轻量级设计,编译速度快

使用方法

1. 添加依赖

在Cargo.toml中添加:

[dependencies]
nanoserde = "0.1"

2. 基本使用示例

use nanoserde::{DeBin, SerBin, DeJson, SerJson};

#[derive(DeBin, SerBin, DeJson, SerJson)]
struct User {
    id: u32,
    name: String,
    active: bool,
}

fn main() {
    // 序列化示例
    let user = User {
        id: 1,
        name: "Alice".to_string(),
        active: true,
    };
    
    // 二进制序列化
    let bin_data: Vec<u8> = SerBin::serialize_bin(&user);
    println!("Binary serialized: {:?}", bin_data);
    
    // JSON序列化
    let json_data = SerJson::serialize_json(&user);
    println!("JSON serialized: {}", json_data);
    
    // 反序列化示例
    let user_from_bin: User = DeBin::deserialize_bin(&bin_data).unwrap();
    let user_from_json: User = DeJson::deserialize_json(&json_data).unwrap();
    
    println!("Deserialized user name: {}", user_from_bin.name);
}

3. 支持的数据类型

  • 基本类型:bool, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64
  • String和&str
  • Vec<T>和数组
  • Option<T>
  • 元组(最多16个元素)
  • 自定义结构体和枚举

4. 枚举类型支持

#[derive(DeBin, SerBin, DeJson, SerJson)]
enum Message {
    Text(String),
    Number(i32),
    Quit,
}

fn enum_example() {
    let msg = Message::Text("Hello".to_string());
    let bin_data = SerBin::serialize_bin(&msg);
    let deserialized: Message = DeBin::deserialize_bin(&bin_data).unwrap();
}

5. 自定义字段名(JSON序列化)

#[derive(DeJson, SerJson)]
struct Person {
    #[n(rename = "firstName")]
    first_name: String,
    #[n(rename = "lastName")]
    last_name: String,
}

注意事项

  1. 确保所有字段类型都实现了相应的trait
  2. 二进制格式不保证跨平台兼容性
  3. 对于复杂嵌套结构,建议使用更成熟的序列化库如serde
  4. 主要用于简单的数据结构和内部通信场景

性能建议

  • 对于性能敏感的场景,优先使用二进制格式
  • 避免在热路径中频繁创建临时序列化对象
  • 考虑使用&str代替String以减少内存分配

这个库特别适合需要轻量级序列化解决方案且不希望引入额外依赖的项目。

完整示例demo

// 导入必要的trait
use nanoserde::{DeBin, SerBin, DeJson, SerJson};

// 定义用户结构体,实现所有序列化trait
#[derive(Debug, DeBin, SerBin, DeJson, SerJson)]
struct User {
    id: u32,
    name: String,
    active: bool,
    tags: Vec<String>,
}

// 定义消息枚举,支持多种消息类型
#[derive(Debug, DeBin, SerBin, DeJson, SerJson)]
enum Message {
    Text(String),
    Number(i32),
    UserData(User),
    Quit,
}

// 定义人员结构体,支持JSON字段重命名
#[derive(Debug, DeJson, SerJson)]
struct Person {
    #[n(rename = "firstName")]
    first_name: String,
    #[n(rename = "lastName")]
    last_name: String,
    age: u8,
}

fn main() {
    println!("=== nanoserde-derive 完整示例 ===");
    
    // 示例1: 基本结构体序列化
    println!("\n1. 基本结构体序列化示例:");
    let user = User {
        id: 42,
        name: "Bob".to_string(),
        active: true,
        tags: vec!["rust".to_string(), "developer".to_string()],
    };
    
    // 二进制序列化与反序列化
    let bin_data: Vec<u8> = SerBin::serialize_bin(&user);
    println!("二进制数据长度: {} bytes", bin_data.len());
    
    let user_from_bin: User = DeBin::deserialize_bin(&bin_data).unwrap();
    println!("从二进制反序列化: {:?}", user_from_bin);
    
    // JSON序列化与反序列化
    let json_data = SerJson::serialize_json(&user);
    println!("JSON数据: {}", json_data);
    
    let user_from_json: User = DeJson::deserialize_json(&json_data).unwrap();
    println!("从JSON反序列化: {:?}", user_from_json);
    
    // 示例2: 枚举类型序列化
    println!("\n2. 枚举类型序列化示例:");
    let messages = vec![
        Message::Text("Hello World".to_string()),
        Message::Number(100),
        Message::UserData(user),
        Message::Quit,
    ];
    
    for msg in messages {
        let json_msg = SerJson::serialize_json(&msg);
        println!("枚举JSON: {}", json_msg);
        
        let bin_msg: Vec<u8> = SerBin::serialize_bin(&msg);
        println!("枚举二进制长度: {} bytes", bin_msg.len());
    }
    
    // 示例3: 字段重命名示例
    println!("\n3. JSON字段重命名示例:");
    let person = Person {
        first_name: "张".to_string(),
        last_name: "三".to_string(),
        age: 30,
    };
    
    let person_json = SerJson::serialize_json(&person);
    println!("重命名字段JSON: {}", person_json);
    
    // 验证反序列化
    let person_from_json: Person = DeJson::deserialize_json(&person_json).unwrap();
    println!("反序列化人员: {:?}", person_from_json);
    
    println!("\n=== 示例执行完成 ===");
}

// 单元测试示例
#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_basic_serialization() {
        let user = User {
            id: 1,
            name: "Test".to_string(),
            active: false,
            tags: vec![],
        };
        
        // 测试二进制往返
        let bin_data = SerBin::serialize_bin(&user);
        let decoded: User = DeBin::deserialize_bin(&bin_data).unwrap();
        assert_eq!(user.id, decoded.id);
        assert_eq!(user.name, decoded.name);
        
        // 测试JSON往返
        let json_data = SerJson::serialize_json(&user);
        let decoded_json: User = DeJson::deserialize_json(&json_data).unwrap();
        assert_eq!(user.active, decoded_json.active);
    }
    
    #[test]
    fn test_enum_serialization() {
        let msg = Message::Text("test".to_string());
        let bin_data = SerBin::serialize_bin(&msg);
        let decoded: Message = DeBin::deserialize_bin(&bin_data).unwrap();
        
        if let Message::Text(text) = decoded {
            assert_eq!(text, "test");
        } else {
            panic!("枚举反序列化失败");
        }
    }
}

这个完整示例展示了nanoserde-derive库的主要功能,包括:

  • 基本结构体的二进制和JSON序列化
  • 枚举类型的序列化支持
  • JSON字段重命名功能
  • 完整的往返序列化测试
  • 单元测试示例

要运行此示例,请确保在Cargo.toml中添加了正确的依赖项,然后使用cargo run命令执行。

回到顶部