【rust 第三方库】serde 序列化反序列化框架

1 serde 框架

官网:https://serde.rs/

作用:可以将结构体、枚举、向量、哈希表等rust数据转换为各种各式的数据(目前为16种)例如JSONYALMTOML等,以及将这些格式的数据转换为原始的rust数据类型

简介

Serde是主流的rust序列化、反序列化框架。设计上,基于rust的静态类型系统和元编程(宏)的能力,使Serde序列化的执行速度与手写序列化器的速度相同。

使用上及其简单

  • 用户为自己的类型实现SerializeDeserialize特质即可(大多数使用derive宏实现)
  • 序列化提供商,提供SerializerDeserializer特征的实现即可。

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使用零拷贝技术)
  • byte array -[u8] (字节数组)
    • 与字符串相似,在反序列化期间,字节数组可以是 transient, 拥有所有权, 和借用
  • option
    • None 或者 Value
  • unit (元组)
    • Rust 中 () 的类型,它表示不包含数据的匿名值
  • unit_struct
    • 例如 struct UnitPhantomData<T>,它表示不包含数据的命名值
  • unit_variant
    • 例如 在 enum E { A, B } 中的 E::AE::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:短横线命名法
  • #[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 方法

  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(())
      }
      
  2. to_value

    • 原型

      pub fn to_value<T>(value: T) -> Result<Value, Error> 
      where
          T: Serialize, 
      
    • 功能:将 转换Tserde_yaml::Value可以表示任何有效 YAML 数据的枚举。

      如果想要一个 Value 而不是字符串,你可以使用 serde_yaml::ser::Serializer 来手动序列化你的结构体到 Value。但这样做通常比直接序列化到字符串更加复杂和低效。

    • 示例

      
      
  3. 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).
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值