#serde #model #run-time #dynamic #inspection #serialization #deserialize

nightly serde_dynamic_typing

一个简化的与 serde 兼容的类型模型,允许动态运行时检查

2 个版本

0.1.1 2021 年 8 月 25 日
0.1.0 2021 年 8 月 24 日

#1356编码

BSD-2-Clause OR MIT

56KB
1.5K SLoC

docs.rs License BSD-2-Clause License MIT crates.io Download numbers AppVeyor CI dependency status

serde_dynamic_typing

欢迎来到 serde_dynamic_typing 🎉

此crate实现了一个简化的与 serde 兼容的类型模型,它以简化的形式表示各种Rust数据结构,并允许动态运行时检查。此类型模型也可用作自定义序列化器等的中间表示。

为什么?

由于Rust编译器擦除了大部分类型信息,这使得运行时检查和修改基本上变得不可能。虽然有一些强大的方式,如 Any 特性或 serde,但是前者主要用于实现动态接口,而后者旨在提供预定义静态数据结构的(反)序列化。

serde_dynamic_typing 处于中间位置:一方面,它类似于 Any,因为它提供了一个简化的类型模型,可以用于在运行时动态构建和检查几乎任意复杂的数据结构。另一方面,它力求与 serdeserde_derive 兼容,因此您可以转换现有的Rust类型和结构体到 AnyValue 以及反之。

此外,它还可以作为 serde 的简单抽象层:虽然 serde 非常灵活和高效,但它也要求更复杂的类型模型和实现。如果您只想编写一个简单的(反)序列化器,而不需要 serde 提供的完整效率和功能,则 serde_dynamic_typing 可以大大简化实现。

详细信息和示例

整个数据模型基于几个核心类型和一个基于枚举的“通用”值类型。

简化的类型有

  • Boolean 代表布尔值
  • Bytes 代表字节容器,如 Vec<u8>[u8][u8; N]
  • Enumeration 代表具有可选关联值的 Rust 原生 enum
  • Float 代表浮点数
  • Integer 代表整数类型
  • Map 代表类似 BTreeMap 的映射类型,也用于表示具有命名字段的 structenum
  • Sequence 代表序列类型,如 Vec<...>[...][...; N],具有任意值,也用于表示具有元组字段的 structenum
  • Utf8String 代表类似 Stringstrchar 的 UTF-8 字符串类型

此外,还有一个“泛型”枚举类型 AnyValue,可以存储上述类型的任何值。

例如,一个类似的结构体

#[derive(Serialize, Deserialize)]
struct ByteContainer {
    #[serde(with = "serde_bytes")]
    bytes: Vec<u8>
}

表示为

AnyValue::Map([
    (
        AnyValue::Utf8String(Utf8String::from("bytes")),      // <- map key
        AnyValue::Bytes(Bytes::from(/* value of `bytes` */))  // <- associated value
    )
])

依赖关系

~125–365KB