Serde:基础框架
Serde 是 Rust 的序列化框架——零成本抽象,编译时代码生成。
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct User {
name: String,
age: u32,
#[serde(default)]
email: Option<String>,
#[serde(rename = "createdAt")]
created_at: chrono::DateTime<chrono::Utc>,
}
// 序列化
let user = User {
name: "张三".to_string(),
age: 30,
email: Some("zhangsan@example.com".to_string()),
created_at: chrono::Utc::now(),
};
let json = serde_json::to_string_pretty(&user)?;
// 反序列化
let parsed: User = serde_json::from_str(&json)?;
字段属性
在字段级别控制序列化行为:
#[derive(Serialize, Deserialize)]
struct Config {
// 重命名以兼容 JSON
#[serde(rename = "databaseUrl")]
database_url: String,
// None 时跳过
#[serde(skip_serializing_if = "Option::is_none")]
optional_field: Option<String>,
// 缺失时使用默认值
#[serde(default = "default_timeout")]
timeout: u64,
// 始终跳过
#[serde(skip)]
internal_state: Vec<u8>,
// 展平嵌套结构
#[serde(flatten)]
metadata: HashMap<String, serde_json::Value>,
}
fn default_timeout() -> u64 {
30
}
自定义序列化
实现 Serialize 和 Deserialize 以获得完全控制:
use serde::{Deserializer, Serializer};
use serde::de::{self, Visitor};
use std::fmt;
struct CustomDate(chrono::NaiveDate);
impl Serialize for CustomDate {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let s = self.0.format("%Y-%m-%d").to_string();
serializer.serialize_str(&s)
}
}
impl<'de> Deserialize<'de> for CustomDate {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct DateVisitor;
impl<'de> Visitor<'de> for DateVisitor {
type Value = CustomDate;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("YYYY-MM-DD 格式的日期字符串")
}
fn visit_str<E>(self, value: &str) -> Result<CustomDate, E>
where
E: de::Error,
{
chrono::NaiveDate::parse_from_str(value, "%Y-%m-%d")
.map(CustomDate)
.map_err(de::Error::custom)
}
}
deserializer.deserialize_str(DateVisitor)
}
}
枚举序列化
在 JSON 中处理 Rust 枚举:
#[derive(Serialize, Deserialize)]
#[serde(tag = "type")]
enum Shape {
Circle { radius: f64 },
Rectangle { width: f64, height: f64 },
Triangle { base: f64, height: f64 },
}
// {"type": "Circle", "radius": 5.0}
let circle = Shape::Circle { radius: 5.0 };
let json = serde_json::to_string(&circle)?;
// 外部标签(默认)
#[derive(Serialize, Deserialize)]
enum Color {
Red,
Green,
Blue,
}
// "Red"
// 相邻标签
#[derive(Serialize, Deserialize)]
#[serde(tag = "t", content = "c")]
enum Value {
Int(i64),
Text(String),
}
// {"t": "Int", "c": 42}
// 无标签枚举
#[derive(Serialize, Deserialize)]
#[serde(untagged)]
enum Value {
Int(i64),
Text(String),
Bool(bool),
}
// 按顺序尝试:先 Int,再 Text,最后 Bool
错误处理
健壮的 JSON 解析与正确的错误类型:
use thiserror::Error;
#[derive(Error, Debug)]
enum JsonError {
#[error("JSON 解析错误: {0}")]
Parse(#[from] serde_json::Error),
#[error("验证错误: {message}")]
Validation { message: String },
#[error("缺失字段: {field}")]
MissingField { field: String },
}
fn parse_config(json: &str) -> Result<Config, JsonError> {
let config: Config = serde_json::from_str(json)?;
if config.database_url.is_empty() {
return Err(JsonError::MissingField {
field: "databaseUrl".to_string(),
});
}
Ok(config)
}
处理动态 JSON
对于未知结构,使用 serde_json::Value:
use serde_json::{Value, json};
// 解析为动态 Value
let data: Value = serde_json::from_str(json_string)?;
// 访问字段
let name = data["name"].as_str().unwrap_or("未知");
let age = data["age"].as_i64().unwrap_or(0);
// 使用 json! 宏构建 JSON
let user = json!({
"name": "张三",
"age": 30,
"tags": ["rust", "json"]
});
// 将 Value 转回字符串
let output = serde_json::to_string_pretty(&user)?;
性能优化
使用 simd-json 加速解析
use simd_json::prelude::*;
let mut data = json_string.to_owned();
let parsed: User = simd_json::from_str(&mut data)?;
// 大型载荷比 serde_json 快 2-3 倍
使用 borrow 避免分配
#[derive(Deserialize)]
struct User<'a> {
name: &'a str, // 从输入字符串借用
age: u32,
}
let user: User = serde_json::from_str(&json)?;
// 字符串字段无需分配
流式处理大文件
use serde_json::Deserializer;
let reader = std::fs::File::open("large.json")?;
let stream = Deserializer::from_reader(reader).into_iter::<User>();
for result in stream {
let user = result?;
process_user(user);
}
// 注意:仅适用于 NDJSON(换行分隔的 JSON)格式
相关资源
- JSON 最佳实践 — 通用最佳实践指南
- JSON Schema 完全指南 — 验证你的 JSON 结构
- JSON 安全最佳实践 — 防范常见漏洞
- JSON 格式化工具 — 在线格式化和验证 JSON
- JSON 压缩工具 — 压缩 JSON 减小体积