文章目录
1 serde 框架
官网:https://serde.rs/
作用:可以将结构体、枚举、向量、哈希表等rust数据转换为各种各式的数据(目前为16种)例如JSON
、YALM
、TOML
等,以及将这些格式的数据转换为原始的rust数据类型
简介
Serde
是主流的rust序列化、反序列化框架。设计上,基于rust的静态类型系统和元编程(宏)的能力,使Serde
序列化的执行速度与手写序列化器的速度相同。
使用上及其简单
- 用户为自己的类型实现
Serialize
和Deserialize
特质即可(大多数使用derive
宏实现) - 序列化提供商,提供
Serializer
和Deserializer
特征的实现即可。
Serde数据模型
Serde
数据模型是与rust数据结构和数据格式进行交互的API。可以将其视为Serde
的类型系统,Serde
将rust类型分为29种。
- 针对需要序列化的类型,用户需要实现
serialize
:根据rust类型调用参数Serializer
上的方法,而Serializer
的实现有序列化提供商提供 - 针对需要反序列化的类型,用户需要实现
Deserialize
:根据rust类型调用参数Serializer
上的方法,传递一个实现了Visitor
的类型
29种类型
- 14 基础类型
- bool
- i8, i16, i32, i64, i128
- u8, u16, u32, u64, u128
- f32, f64
- char
- string
- 有长度标记的UTF-8 字节数据(不是
\0
结尾的形式),可能长度为0 - 在序列化时,所有类型的字符串被同等处理。在反序列化时,有三种方案:transient, 拥有所有权, 和借用。参见《理解反序列化生命周期》,(Serde使用零拷贝技术)
- 有长度标记的UTF-8 字节数据(不是
- byte array -
[u8]
(字节数组)- 与字符串相似,在反序列化期间,字节数组可以是 transient, 拥有所有权, 和借用
- option
- None 或者 Value
- unit (元组)
- Rust 中
()
的类型,它表示不包含数据的匿名值
- Rust 中
- unit_struct
- 例如
struct Unit
或PhantomData<T>
,它表示不包含数据的命名值
- 例如
- unit_variant
- 例如 在
enum E { A, B }
中的E::A
和E::B
- 例如 在
- newtype_struct
- 例如
struct Millimeters(u8)
- 例如
- newtype_variant
- 例如 在
enum E { N(u8) }
中的E::N
- 例如 在
- seq
- 可变大小的异质序列
- 例如
Vec<T>
或者HashSet<T>
- 序列化时,长度在遍历之前可能是未知的。在反序列化时,通过 查看数据 可以得知长度
- 注意,像
vec![Value::Bool(true), Value::Char('c')]
之类的同质Rust集合可以序列化为异构Serde seq,在这种情况下,包含Serde bool和Serde char。
- tuple
- 大小静态可知的异质序列
- 例如
(u8,)
或(String, u64, Vec<T>)
或[u64; 10]
- 其长度在反序列化时就已知道,无需查看数据
- tuple_struct
- 命名元组,例如
struct Rgb(u8, u8, u8)
- 命名元组,例如
- tuple_variant
- 例如 在
enum E { T(u8, u8) }
中 的E::T
- 例如 在
- map
- 大小可变的异类键值对,例如
BTreeMap <K, V>
。进行序列化时,在遍历所有条目之前,长度可能未知,也可能未知。反序列化时,通过 查看数据 可以得知长度
- 大小可变的异类键值对,例如
- struct
- 静态大小的异构键值对,其中的键是编译时常量字符串,并且在反序列化时无需查看序列化数据即可知道
- 例如
struct S { r: u8, g: u8, b: u8 }
- struct_variant
- 例如 在
enum E { S { r: u8, g: u8, b: u8 } }
中 的E::S
- 例如 在
属性
属性用于使用派生宏的一些配置,主要分为三类:
- 容器属性
Container attributes
:应用在枚举
和结构体上
- 变体属性
Variant attributes
:应用在枚举
的变体
上 - 字段属性
Field attributes
:应用在结构体
和枚举变体
的 字段上
1)容器属性
-
#[serde(rename_all = "...")]
- 根据给定的大小写约定重命名所有字段(结构)或 variants(枚举)。
"..."
的可选值为"lowercase"
,"UPPERCASE"
,"PascalCase"
,"camelCase"
,"snake_case"
,"SCREAMING_SNAKE_CASE"
,"kebab-case"
,"SCREAMING-KEBAB-CASE"
- kebab-case:短横线命名法
- 根据给定的大小写约定重命名所有字段(结构)或 variants(枚举)。
-
#[serde(deny_unknown_fields)]
- 指定遇到未知字段时,在反序列化期间始终出错。
- 默认情况下,对于诸如JSON之类的自描述格式,未知字段将被忽略
2)变体属性
#[serde(alias = "name")]
- 反序列化时,对应的别名
- 允许配置多个
#[serde(skip)]
- 跳过序列化或反序列化此 variant
- 尝试序列化时将报错
- 尝试反序列化时将报错
3)字段属性
#[serde(alias = "name")]
- 反序列化时,对应的别名
- 允许配置多个
#[serde(skip)]
- 跳过此字段:不序列化或反序列化
- 反序列化时,Serde将使用
Default::default()
或default = "..."
生成该值
2 使用第三方库序列化(serde_yaml)
2.1 序列化
1 方法
-
to_string
-
原型
pub fn to_string<T>(value: &T) -> Result<String, Error> where T: ?Sized + Serialize,
-
功能:将给定的数据结构序列化为 YAML 字符串。
-
示例
fn to_string() -> Result<(), Box<dyn std::error::Error>>{ let people = People{ name:"Alice".to_string(), age:30, email:"123456".to_string(), }; let yaml_string = serde_yaml::to_string(&people)?; println!("{}", yaml_string); Ok(()) }
-
-
to_value
-
原型
pub fn to_value<T>(value: T) -> Result<Value, Error> where T: Serialize,
-
功能:将 转换
T
为serde_yaml::Value
可以表示任何有效 YAML 数据的枚举。如果想要一个
Value
而不是字符串,你可以使用serde_yaml::ser::Serializer
来手动序列化你的结构体到Value
。但这样做通常比直接序列化到字符串更加复杂和低效。 -
示例
-
-
to_writer
-
原型
pub fn to_writer<W, T>(writer: W, value: &T) -> Result<(), Error> where W: Write, T: ?Sized + Serialize,
-
功能:将给定的数据结构作为 YAML 序列化到 IO 流中。
-
示例
fn to_writer() { let people = People{ name:"Alice".to_string(), age:2, email:"123456".to_string(), }; let mut out = Vec::new(); serde_yaml::to_writer(&mut out, &people).
-