Serde:Rust 序列化與反序列化框架

Serde 是 Rust 生態系統中的核心函式庫,提供了高效且通用的序列化與反序列化框架。其名稱源自 "Serialization" 與 "Deserialization" 的組合。

主要特色

  • 通用性:支援多種資料格式,如 JSON、YAML、TOML、MessagePack 等
  • 零成本抽象:編譯時產生的程式碼與手寫程式碼同樣高效
  • 靈活性:可自訂序列化與反序列化行為
  • 強型別:利用 Rust 的型別系統確保資料完整性
  • 廣泛應用:已成為 Rust 生態系統中處理資料交換的標準函式庫

運作原理

Serde 的核心在於其中間表示(Intermediate Representation)設計,它將序列化與反序列化過程分為兩步:

  1. 序列化:將 Rust 資料結構轉換為通用中間表示,再轉換為目標格式
  2. 反序列化:將輸入格式轉換為通用中間表示,再轉換為 Rust 資料結構

這種設計允許新增資料格式,而無需修改使用 Serde 的應用程式。

基本用法

設定依賴

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" # 或其他格式函式庫如 serde_yaml、toml 等

派生巨集用法

最常見的用法是使用派生巨集為結構體自動實現序列化與反序列化特性:

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let point = Point { x: 1, y: 2 };

    // 將 Point 轉換為 JSON 字串
    let serialized = serde_json::to_string(&point).unwrap();
    println!("序列化結果: {}", serialized); // 輸出: {"x":1,"y":2}

    // 將 JSON 字串轉換回 Point
    let deserialized: Point = serde_json::from_str(&serialized).unwrap();
    println!("反序列化結果: {:?}", deserialized); // 輸出: Point { x: 1, y: 2 }
}

屬性自訂

Serde 提供了豐富的屬性來自訂序列化行為:

#[derive(Serialize, Deserialize, Debug)]
struct User {
    #[serde(rename = "user_id")]
    id: u64,
    
    #[serde(default)]
    name: String,
    
    #[serde(skip_serializing_if = "Option::is_none")]
    email: Option<String>,
    
    #[serde(skip)]
    temporary_data: usize,
}

支援的資料格式

Serde 與多種資料格式整合,每種格式都有獨立的 crate:

  • serde_json:JSON 格式
  • serde_yaml:YAML 格式
  • toml:TOML 格式
  • bincode:二進位格式
  • postcard:空間最佳化的二進位格式
  • rmp/rmp-serde:MessagePack 格式
  • ciborium:CBOR 格式
  • ...等其他格式

進階用法

手動實現特性

對於特殊需求,可以手動實現 SerializeDeserialize 特性:

use serde::{Serialize, Serializer, Deserialize, Deserializer};

struct MyType {
    // 欄位...
}

impl Serialize for MyType {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        // 自訂序列化邏輯
    }
}

impl<'de> Deserialize<'de> for MyType {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        // 自訂反序列化邏輯
    }
}

型別對映

可以在不同資料表示之間建立對映:

#[derive(Serialize, Deserialize)]
#[serde(remote = "chrono::DateTime<chrono::Utc>")]
struct DateTimeRef {
    #[serde(with = "chrono::serde::ts_seconds")]
    pub inner: chrono::DateTime<chrono::Utc>,
}

學習與資源

Serde 是一個功能豐富的函式庫,本文僅涵蓋基礎知識。若要充分利用 Serde,建議讀者:

  1. 造訪 Serde 官方文件 了解詳細 API 與範例
  2. 查看 GitHub 儲存庫 取得原始碼與最新更新

結語

Serde 作為 Rust 生態系統中的基礎函式庫,為資料交換提供了強大而靈活的工具。透過掌握 Serde,您可以輕鬆處理各種格式的資料交換需求,使應用程式更加強大且具備互通性。