Rust序列化与反序列化宏库musli-macros的使用,提供高效灵活的编译时数据转换支持

Rust序列化与反序列化宏库musli-macros的使用,提供高效灵活的编译时数据转换支持

musli-macros是Müsli框架中提供宏支持的crate,它为Rust提供了高效的编译时序列化和反序列化支持。

github crates.io ![docs.rs](https://img.shields.io/badge/docs.rs-musli--macros-66c2a5?style=for-the-badge&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik004ODcuNiAyNTAuMkwzOTIgMjE0VjEwNS5jMC0xNS9.3LTI4LjQtMjMuNC0zMy7sLTEwMC0zNS5jLTguMS-3LjEtMTcuMS-3LjEtMj5.3IDBsLTEwMCAzNS5jLTE0LjUgNS3-y3.4IDE4LjctMj3.4ID33.7VjIxNGwtOTYuNiMz6.2QzkuMyAyNTUu5IDAgMj68.9IDAgMj83L9WMzk0YzAgMT3.6 7.7ID26.1IDE5.9ID32L2wxMDAgNTBjMTAuMSA1LjEgMjIuMSA1LjEgMzI.2IDBsMTAzL9-52AxMD3.9IDUyYzEwLjEgNSAxMjIuMSA1LjEgMzIu2IDBsMTAwLTUwYzEyLjItNiAxOS9tLTE4Lj6gMT5tLT32L2VWMjgzL9jMC0xMy9.3LTI4.4LTI3.4-33N7zTT35OCAyMTQuOGwt85 3MS9Wv-68Mmw4NS0zNnY73.zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyID38LjJ2LjZsLTEwMiA0MS4yLTEwMi00MS4ydi6NZm08NCAy91LjFsLT85IDQyL5V2LT79LjFsODMtMz8udv75NHomMC0xMTJsLTE0MiA0MS40LTEwMi04MS4ydi6uNmwxMDItMzguMiAxMDIgMzguMnYuNHptMjQwIDExMmwt85 42L5V2LT79LjFsODUtMz8udv75NHomMC0xMTJsLTEwMiA41LjYtMTAyLTQ1LjZ2Lv6uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K) build status

安装

在项目目录中运行以下Cargo命令:

cargo add musli-macros

或者在Cargo.toml中添加以下行:

musli-macros = "0.0.131"

完整示例

以下是一个使用musli-macros进行序列化和反序列化的完整示例:

use musli::{Encode, Decode};

#[derive(Encode, Decode)]
struct Person {
    name: String,
    age: u32,
    email: Option<String>,
}

fn main() {
    let person = Person {
        name: "Alice".to_string(),
        age: 30,
        email: Some("alice@example.com".to_string()),
    };

    // 序列化
    let encoded = musli::json::to_vec(&person).unwrap();
    println!("Serialized: {}", String::from_utf8_lossy(&encoded));

    // 反序列化
    let decoded: Person = musli::json::from_slice(&encoded).unwrap();
    println!("Deserialized: {} {} {:?}", decoded.name, decoded.age, decoded.email);
}

这个示例展示了:

  1. 使用#[derive(Encode, Decode)]宏自动为结构体生成序列化和反序列化实现
  2. 使用musli的json格式进行序列化和反序列化
  3. 处理包含可选字段的结构体

特点

  1. 编译时生成代码,运行时性能高
  2. 支持无标准库(no-std)环境
  3. 支持无动态分配(no-alloc)场景
  4. 提供灵活的序列化格式支持

注意事项

musli-macros的API不保证稳定性,建议通过muslimusli_core crate来使用这些宏,而不是直接使用musli-macros。


1 回复

Rust序列化与反序列化宏库musli-macros使用指南

概述

musli-macros是一个Rust宏库,为musli序列化框架提供编译时派生支持。它允许通过派生宏自动实现序列化和反序列化逻辑,提供高效灵活的数据转换能力。

主要特性

  • 零拷贝序列化支持
  • 编译时类型检查
  • 高度可配置的序列化行为
  • 同时支持二进制和文本格式
  • 良好的错误处理机制

安装

在Cargo.toml中添加依赖:

[dependencies]
musli-macros = "0.4"
musli = "0.4"

基本使用

1. 派生Serialize和Deserialize

use musli_macros::{Serialize, Deserialize};

#[derive(Debug, Serialize, Deserialize)]
struct Person {
    name: String,
    age: u32,
    hobbies: Vec<String>,
}

#[derive(Debug, Serialize, Deserialize)]
enum Message {
    Text(String),
    Image { width: u32, height: u32 },
}

2. 序列化和反序列化

use musli::json; // 或者 musli::wire 用于二进制格式

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let person = Person {
        name: "Alice".to_string(),
        age: 30,
        hobbies: vec!["reading".to_string(), "hiking".to_string()],
    };
    
    // 序列化为JSON
    let json = json::to_string(&person)?;
    println!("Serialized: {}", json);
    
    // 从JSON反序列化
    let deserialized: Person = json::from_str(&json)?;
    println!("Deserialized: {:?}", deserialized);
    
    Ok(())
}

高级用法

1. 自定义字段名称

#[derive(Serialize, Deserialize)]
struct User {
    #[musli(rename = "userName")]
    username: String,
    #[musli(rename = "createdAt")]
    created_at: u64,
}

2. 跳过字段

#[derive(Serialize, Deserialize)]
struct Config {
    api_key: String,
    #[musli(skip)]
    internal_secret: String,
}

3. 自定义编解码器

use musli::mode::DefaultMode;
use musli::context::DefaultContext;
use musli::encoding::{Encoder, Decoder};

#[derive(Serialize, Deserialize)]
struct CustomData {
    #[musli(codec_with = "custom_codec")]
    value: String,
}

fn custom_codec<M, E, C>(encoder: E, value: &str) -> Result<E::Ok, E::Error>
where
    M: musli::mode::Mode,
    E: Encoder<M>,
{
    encoder.encode_string(&value.to_uppercase())
}

fn custom_decode<'de, M, D, C>(decoder: D) -> Result<String, D::Error>
where
    M: musli::mode::Mode,
    D: Decoder<'de, M>,
{
    let s = decoder.decode_string()?;
    Ok(s.to_lowercase())
}

4. 使用枚举标记

#[derive(Serialize, Deserialize)]
#[musli(tag = "type")]
enum Event {
    Click { x: i32, y: i32 },
    KeyPress(char),
}

性能提示

  1. 对于性能敏感场景,考虑使用musli::wire二进制格式而非JSON
  2. 在可能的情况下使用&str而非String以减少分配
  3. 对于大型结构,考虑使用#[musli(packed)]以减少编码大小

错误处理

musli提供了详细的错误信息,可以通过musli::error::Error类型捕获和处理序列化/反序列化错误:

match json::from_str::<Person>(invalid_json) {
    Ok(person) => println!("Success: {:?}", person),
    Err(e) => eprintln!("Error: {}", e),
}

与其他库比较

相比serde,musli-macros提供了:

  • 更灵活的配置选项
  • 更好的零拷贝支持
  • 更细粒度的控制 但生态系统可能不如serde成熟。

完整示例代码

// 完整示例演示musli-macros的各种功能
use musli_macros::{Serialize, Deserialize};
use musli::json;

// 基本结构体示例
#[derive(Debug, Serialize, Deserialize)]
struct Book {
    title: String,
    author: String,
    #[musli(rename = "pubYear")]
    pub_year: u32,
    #[musli(skip)]
    internal_id: u64,
}

// 枚举示例
#[derive(Debug, Serialize, Deserialize)]
#[musli(tag = "eventType")]
enum Event {
    Login { user_id: u64, timestamp: u64 },
    Purchase { item_id: String, amount: f64 },
}

// 自定义编解码器示例
#[derive(Debug, Serialize, Deserialize)]
struct SecretMessage {
    #[musli(codec_with = "encode_secret", decode_with = "decode_secret")]
    content: String,
}

fn encode_secret<M, E, C>(encoder: E, value: &str) -> Result<E::Ok, E::Error>
where
    M: musli::mode::Mode,
    E: musli::encoding::Encoder<M>,
{
    // 简单的编码示例 - 实际应用中应该使用真正的加密
    let encoded = value.chars().rev().collect::<String>();
    encoder.encode_string(&encoded)
}

fn decode_secret<'de, M, D, C>(decoder: D) -> Result<String, D::Error>
where
    M: musli::mode::Mode,
    D: musli::encoding::Decoder<'de, M>,
{
    let s = decoder.decode_string()?;
    // 解码我们简单的编码
    Ok(s.chars().rev().collect::<String>())
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 基本结构体序列化/反序列化
    let book = Book {
        title: "Rust编程".to_string(),
        author: "某作者".to_string(),
        pub_year: 2023,
        internal_id: 12345,
    };
    
    let book_json = json::to_string(&book)?;
    println!("Book JSON: {}", book_json);
    let book_deserialized: Book = json::from_str(&book_json)?;
    println!("Deserialized Book: {:?}", book_deserialized);
    
    // 2. 枚举序列化/反序列化
    let event = Event::Purchase {
        item_id: "item_123".to_string(),
        amount: 29.99,
    };
    
    let event_json = json::to_string(&event)?;
    println!("Event JSON: {}", event_json);
    let event_deserialized: Event = json::from_str(&event_json)?;
    println!("Deserialized Event: {:?}", event_deserialized);
    
    // 3. 自定义编解码器示例
    let secret = SecretMessage {
        content: "这是一个秘密消息".to_string(),
    };
    
    let secret_json = json::to_string(&secret)?;
    println!("Secret JSON: {}", secret_json);
    let secret_deserialized: SecretMessage = json::from_str(&secret_json)?;
    println!("Deserialized Secret: {:?}", secret_deserialized);
    
    Ok(())
}

希望这个指南和完整示例能帮助你开始使用musli-macros进行Rust数据序列化!

回到顶部