百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程文章 > 正文

Rust语言从入门到精通系列 - Serde序列化/反序列化模块入门指北

qiyuwang 2025-05-02 20:46 3 浏览 0 评论

Serde 是一个用于序列化和反序列化 Rust 数据结构的库。它支持 JSON、BSON、YAML 等多种格式,并且可以自定义序列化和反序列化方式。Serde 的特点是代码简洁、易于使用、性能高效。它是 Rust 生态中最受欢迎的序列化库之一。

基础用法

安装

在 Rust 项目中使用 Serde,需要在Cargo.toml文件中添加如下依赖:

[dependencies]
serde = { version = "1.0", features = ["derive"] }

其中features = ["derive"]表示使用 Serde 的派生宏,可以自动生成序列化和反序列化代码。

序列化

使用 Serde 进行序列化,需要先将数据结构实现serde::Serialize trait。例如,我们定义一个Animal结构体,包含名称和年龄两个字段:

#[derive(Serialize)]
struct Animal {
    name: String,
    age: u32,
}

然后,我们可以使用serde_json库将Animal结构体序列化为 JSON 字符串:

use serde_json;

let animal = Animal {
    name: "Tom".to_owned(),
    age: 3,
};
let json = serde_json::to_string(&animal).unwrap();
println!("{}", json); // {"name":"Tom","age":3}

反序列化

使用 Serde 进行反序列化,需要先将数据结构实现serde::Deserialize trait。例如,我们定义一个Animal结构体,包含名称和年龄两个字段:

#[derive(Deserialize)]
struct Animal {
    name: String,
    age: u32,
}

然后,我们可以使用serde_json库将 JSON 字符串反序列化为Animal结构体:

use serde_json;

let json = r#"{"name":"Tom","age":3}"#;
let animal: Animal = serde_json::from_str(json).unwrap();
println!("{:?}", animal); // Animal { name: "Tom", age: 3 }

进阶用法

自定义序列化和反序列化

如果默认的序列化和反序列化方式无法满足需求,可以自定义序列化和反序列化方式。例如,我们定义一个Animal结构体,包含名称和年龄两个字段,但是希望在序列化时,将名称转换为大写字母,反序列化时,将名称转换为小写字母:

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

#[derive(Serialize, Deserialize)]
struct Animal {
    #[serde(serialize_with = "serialize_name", deserialize_with = "deserialize_name")]
    name: String,
    age: u32,
}

fn serialize_name<S>(name: &String, serializer: S) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    serializer.serialize_str(&name.to_uppercase())
}

fn deserialize_name<'de, D>(deserializer: D) -> Result<String, D::Error>
where
    D: Deserializer<'de>,
{
    let name = String::deserialize(deserializer)?;
    Ok(name.to_lowercase())
}

Animal结构体中,我们使用#[serde(serialize_with = "serialize_name", deserialize_with = "deserialize_name")]指定了自定义的序列化和反序列化方法。serialize_name函数将名称转换为大写字母,deserialize_name函数将名称转换为小写字母。

序列化和反序列化枚举

Serde 支持序列化和反序列化枚举类型。例如,我们定义一个Animal枚举,包含狗和猫两种类型:

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
enum Animal {
    Dog { name: String, age: u32 },
    Cat { name: String, age: u32 },
}

在序列化和反序列化枚举类型时,需要使用#[serde(tag = "type")]指定枚举类型的标签,例如:

use serde_json;

let dog = Animal::Dog { name: "Tom".to_owned(), age: 3 };
let json = serde_json::to_string(&dog).unwrap();
println!("{}", json); // {"type":"Dog","name":"Tom","age":3}

let json = r#"{"type":"Dog","name":"Tom","age":3}"#;
let dog: Animal = serde_json::from_str(json).unwrap();
println!("{:?}", dog); // Dog { name: "Tom", age: 3 }

序列化和反序列化结构体中的 Option

Serde 支持序列化和反序列化结构体中的Option类型。例如,我们定义一个Animal结构体,包含名称和年龄两个字段,其中名称可以为空:

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Animal {
    name: Option<String>,
    age: u32,
}

在序列化和反序列化结构体中的Option类型时,需要使用#[serde(skip_serializing_if = "Option::is_none")]指定当Option值为None时,不进行序列化。例如:

use serde_json;

let animal = Animal { name: Some("Tom".to_owned()), age: 3 };
let json = serde_json::to_string(&animal).unwrap();
println!("{}", json); // {"name":"Tom","age":3}

let animal = Animal { name: None, age: 3 };
let json = serde_json::to_string(&animal).unwrap();
println!("{}", json); // {"age":3}

let json = r#"{"age":3}"#;
let animal: Animal = serde_json::from_str(json).unwrap();
println!("{:?}", animal); // Animal { name: None, age: 3 }

序列化和反序列化结构体中的 Vec

Serde 支持序列化和反序列化结构体中的Vec类型。例如,我们定义一个Zoo结构体,包含多个Animal

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Zoo {
    animals: Vec<Animal>,
}

在序列化和反序列化结构体中的Vec类型时,Serde 会自动处理序列化和反序列化。例如:

use serde_json;

let zoo = Zoo { animals: vec![
    Animal { name: "Tom".to_owned(), age: 3 },
    Animal { name: "Jerry".to_owned(), age: 2 },
] };
let json = serde_json::to_string(&zoo).unwrap();
println!("{}", json); // {"animals":[{"name":"Tom","age":3},{"name":"Jerry","age":2}]}

let json = r#"{"animals":[{"name":"Tom","age":3},{"name":"Jerry","age":2}]}"#;
let zoo: Zoo = serde_json::from_str(json).unwrap();
println!("{:?}", zoo); // Zoo { animals: [Animal { name: "Tom", age: 3 }, Animal { name: "Jerry", age: 2 }] }

序列化和反序列化结构体中的 HashMap

Serde 支持序列化和反序列化结构体中的HashMap类型。例如,我们定义一个Zoo结构体,包含多个Animal,使用HashMap存储:

use std::collections::HashMap;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Zoo {
    animals: HashMap<String, Animal>,
}

在序列化和反序列化结构体中的HashMap类型时,Serde 会自动处理序列化和反序列化。例如:

use serde_json;

let mut animals = HashMap::new();
animals.insert("Tom".to_owned(), Animal { name: "Tom".to_owned(), age: 3 });
animals.insert("Jerry".to_owned(), Animal { name: "Jerry".to_owned(), age: 2 });
let zoo = Zoo { animals };
let json = serde_json::to_string(&zoo).unwrap();
println!("{}", json); // {"animals":{"Jerry":{"name":"Jerry","age":2},"Tom":{"name":"Tom","age":3}}}

let json = r#"{"animals":{"Jerry":{"name":"Jerry","age":2},"Tom":{"name":"Tom","age":3}}}"#;
let zoo: Zoo = serde_json::from_str(json).unwrap();
println!("{:?}", zoo); // Zoo { animals: {"Tom": Animal { name: "Tom", age: 3 }, "Jerry": Animal { name: "Jerry", age: 2 }} }

总结

本教程介绍了如何使用 Serde 进行序列化和反序列化,并且介绍了如何自定义序列化和反序列化逻辑。使用 Serde 可以轻松地将 Rust 数据结构转换为任何格式,并且可以通过自定义序列化和反序列化逻辑实现更高级的功能。

#大有学问# #每天学点Rust##100天入门Rust##Rust##程序员##哪件事能让你坚持100天##头条创作挑战赛#

相关推荐

PayPal严重漏洞可通过不安全的JAVA反序列化对象

在2015年12月,我在PayPal商业网站(manager.paypal.com)中发现了一个严重的漏洞,这个漏洞的存在,使得我可以通过不安全的JAVA反序列化对象,在PayPal的网站服务器上远程...

提醒:Apache Dubbo存在反序列化漏洞

背景:近日监测到ApacheDubbo存在反序列化漏洞(CVE-2019-17564),此漏洞可导致远程代码执行。ApacheDubbo是一款应用广泛的高性能轻量级的JavaRPC分布式服务框架...

【预警通报】关于WebLogicT3存在反序列化高危漏洞的预警通报

近日,我中心技术支撑单位监测到WebLogicT3存在反序列化0day高危漏洞,攻击者可利用T3协议进行反序列化漏洞实现远程代码执行。...

Apache dubbo 反序列化漏洞(CVE-2023-23638)分析及利用探索

在对Apachedubbo的CVE-2023-23638漏洞分析的过程中,通过对师傅们对这个漏洞的学习和整理,再结合了一些新学的技巧运用,从而把这个漏洞的利用向前推了一步。整个过程中的研究思路以及...

案例|WebLogic反序列化漏洞攻击分析

目前网络攻击种类越来越多,黑客的攻击手段也变得层出不穷,常规的防护手段通常是对特征进行识别,一旦黑客进行绕过等操作,安全设备很难发现及防御。通过科来网络回溯分析系统可以全景还原各类异常网络行为,记录所...

【预警通报】关于ApacheOFBizRMI反序列化远程代码 执行高危漏洞的预警通报

近日,我中心技术支撑单位监测发现ApacheOFBiz官方发布安全更新,修复了一处远程代码执行漏洞。成功利用该漏洞的攻击者可造成任意代码执行,控制服务器。该漏洞编号:CVE-2021-26295,安...

关于OracleWebLogic wls9-async组件存在反序列化远程命令执行高危漏洞的预警通报

近日,国家信息安全漏洞共享平台(CNVD)公布了OracleWebLogicwls9-async反序列化远程命令执行漏洞。攻击者利用该漏洞,可在未授权的情况下远程执行命令。该漏洞安全级别为“高危”。现...

Rust语言从入门到精通系列 - Serde序列化/反序列化模块入门指北

Serde是一个用于序列化和反序列化Rust数据结构的库。它支持JSON、BSON、YAML等多种格式,并且可以自定义序列化和反序列化方式。Serde的特点是代码简洁、易于使用、性能高效。...

Java反序列化漏洞详解(java反序列化漏洞利用)

Java反序列化漏洞从爆出到现在快2个月了,已有白帽子实现了jenkins,weblogic,jboss等的代码执行利用工具。本文对于Java反序列化的漏洞简述后,并对于Java反序列化的Poc进行详...

关于Oracle WebLogic Server存在反序列化远程代码执行漏洞的安全公告

安全公告编号:CNTA-2018-00222018年7月18日,国家信息安全漏洞共享平台(CNVD)收录了OracleWebLogicServer反序列化远程代码执行漏洞(CNVD-2018-13...

CVE-2020-9484 Apache Tomcat反序列化漏洞浅析

本文是i春秋论坛作家「Ybwh」表哥原创的一篇技术文章,浅析CVE-2020-9484ApacheTomcat反序列化漏洞。01漏洞概述这次是因为错误配置和org.apache.catalina....

告别脚本小子系列丨JAVA安全(8)——反序列化利用链(下)

0x01前言...

关于WebLogic反序列化高危漏洞的紧急预警通报

近日,WebLogic官方发布WebLogic反序列化漏洞的紧急预警通告,利用该漏洞可造成远程代码执行并直接控制Weblogic服务器,危害极大。该漏洞编号为:CVE-2019-2890,安全级别为“...

高危!Fastjson反序列化漏洞风险通告

漏洞描述...

学习Vulhub的Java RMI Registry 反序列化漏洞

这个实验,我们先通过dnslog演示命令执行,然后通过反弹shell获得root权限。JavaRemoteMethodInvocation用于在Java中进行远程调用。RMI存在远程bind的...

取消回复欢迎 发表评论: