GoRust Crate

Rust Crate 使用:serde

2019-07-16  本文已影响10人  kayryu

serde

Github
Crates.io

前言

序列化和反序列化是非常通用的功能,在网络传输,数据存储上极其常见的。序列化和反序列化的通用解释是:

seriallization 序列化 : 将对象转化为便于传输的格式, 常见的序列化格式:二进制格式,字节数组,json字符串,xml字符串。
deseriallization 反序列化:将序列化的数据恢复为对象的过程。

介绍

Serde是高效通用的对Rust数据结构进行序列化和反序列化的框架。
Serde生态系统由知道如何序列化和反序列化自身的数据结构,以及知道如何序列化和反序列化其他事物的数据格式。
Serde允许使用任何支持序列化和反序列化的基础数据类型组成的复杂数据结构。

基础类型

开箱即用, Serde支持序列化Rust的所有基础类型,例如String, &str, usize, Vec<T>, HashMap<K,V>,这些都支持。

数据格式

以下是社区为Serde实现的部分数据格式,例如JSON, Bincode, MessagePack, CBOR, YAML, TOML, RON, BSON, JSON5, URL

使用

基于派生宏

首先在Cargo.toml中添加

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

然后在src/main.rs定义Person结构,并实现#[derive(Serialize, Deserialize)]

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Person {
    name: String,
    age: u8,
    phones: Vec<String>,
    weight: Option<u8>,
}

fn main() {
    let data = r#"
        {
            "name": "John Doe",
            "age": 43,
            "phones": [
                "+44 1234567",
                "+44 2345678"
            ]
        }"#;

    // 解析字符串到Person对象。
    let p: Person = serde_json::from_str(data).unwrap();
    println!("Please call {} at the number {}", p.name, p.phones[0]);
    
    // Person对象转为JSON字符串.
    let serialized = serde_json::to_string(&p).unwrap();
    println!("serialized = {}", serialized);
}

输出

Running `target\debug\examples\u-serde.exe`
Please call John Doe at the number +44 1234567
serialized = {"name":"John Doe","age":43,"phones":["+44 1234567","+44 2345678"],"weight":null}

在结构中,我们也可以定义Option类型作为可以缺省字段,不影响反序列化。

但如果我们把age字段在删除了,那么程序运行时会如下错误:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("missing field `age`", line: 8, column: 9)'

其他

上述例子是转化为JSON格式的,如果想转化为YAML格式的,不需要修改结构体,只需在Cargo.toml中引入serde_yaml = "0.8"包。

然后在先前代码后添加如下代码:

let config = serde_yaml::to_string(&p).unwrap();
println!("config = {}", config);

输出

config = ---
name: John Doe
age: 43
phones:
  - +44 1234567
  - +44 234

疑问

  1. 能否支持枚举类型?
  2. 能否支持字段的默认值?
  3. 能否忽略某个字段?
  4. 能否支持字段改名?
  5. 能否自定义序列化?

可以统统可以,上述问题答案都可以在社区例子中找到答案。

参考

serde

上一篇下一篇

猜你喜欢

热点阅读