5 个版本

0.2.3 2021 年 5 月 20 日
0.2.2 2021 年 5 月 2 日
0.2.1 2021 年 4 月 29 日
0.2.0 2021 年 4 月 28 日
0.1.0 2021 年 2 月 3 日

#2830解析器实现

45 每月下载量
3 crate 中使用

MIT/Apache

120KB
3.5K SLoC

Messy Json

Rust 动态结构文档 JSON 解析器

简介

Rust 生态系统允许在编译时很好地实现 JSON 反序列化到 Rust 结构,但是当涉及到动态结构对象的运行时反序列化时,情况就变得有些稀疏。这个 crate 以一种简单的方式解决这个问题,类似于 serde_json's Value

示例

	use messy_json::*;
	use serde::de::DeserializeSeed;

    let nested_string = MessyJson::from(MessyJsonInner::String(MessyJsonScalar::new(false)));
    let schema: MessyJson = MessyJson::from(MessyJsonInner::Obj(MessyJsonObject::from(MessyJsonObjectInner::new(
        vec![(arcstr::literal!("hello"), nested_string)]
            .into_iter()
            .collect(),
        false,
    ))));
    let value = r#"
	{
		"hello": "world"
	}
	"#;

	let mut deserializer = serde_json::Deserializer::from_str(value);
	let parsed: MessyJsonValueContainer = schema.builder(MessyJsonSettings::default()).deserialize(&mut deserializer).unwrap();
	
	println!("{:#?}", parsed)

性能

当所有字段都是必需的时,这个 crate 比使用 serde_json's Value 更有效。当一些字段是可选时,性能与 serde_json's Value 相当。

然而,这个 crate 在使用 serde 的 proc-macro 进行反序列化(这根本不是动态结构)方面落后很多。

当将 Allocator 特性合并到 stable 时,可以使用自定义的基于区域的分配器(如 Bumpalo)来填补这个差距。

这个 crate 实现了基准测试。以下图表是在具有以下配置的机器上运行的

  • CPU:Intel i9-9900K @ 4.7Ghz
  • 内存:32 Gb RAM @ 2133 Mhz
  • 内核:5.11.16-arch1-1
  • Rust:rustc 1.51.0 (2fd73fabe 2021-03-23)

在以下基准测试中,与 serde_json's Value 和使用 serde's derive 生成的宏解析器进行了比较。

虚拟对象

以下基准测试包括反序列化 JSON 文档

{
	"hello":
	{
		"hola": "world"
	}
}

接受的模式应如下所示

use std::borrow::Cow;

struct DummyObjNested<'a> {
    hola: Cow<'a, str>,
}

struct DummyObj<'a> {
    hello: DummyObjNested<'a>,
}

结果显示,messy_json比宏生成的反序列化器慢,但比使用serde_json's Value快。

部分对象

以下基准测试包括反序列化 JSON 文档

{
	"hello":
	{
		"hola": "world"
	}
}

接受的模式应如下所示

use serde::{Serialize, Deserialize};
use std::borrow::Cow;

#[derive(Serialize, Deserialize)]
struct PartialObjNested<'a> {
    hola: Cow<'a, str>,
}

#[derive(Serialize, Deserialize)]
struct PartialObj<'a> {
    hello: PartialObjNested<'a>,
    coucou: Option<Cow<'a, str>>,
    coucou1: Option<Cow<'a, str>>,
    coucou2: Option<Cow<'a, str>>,
}

结果显示,messy_json比宏生成的反序列化器慢,并且与serde_json's Value相当。当使用可选值时,该包必须检查每个对象是否满足所有必需的值,因此性能下降。在未来,当Rust语言的alloc_api合并到stable时,可以实施优化,以减少检查缺失字段所需的时间。

简单对象

以下基准测试包括反序列化 JSON 文档

{
	"hello": "world"
}

接受的模式应如下所示

use std::borrow::Cow;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct SimpleObj<'a> {
    hello: Cow<'a, str>,
}

结果显示,messy_json比宏生成的反序列化器慢,但仍然比serde_json's Value快。

依赖关系

~0.8–1.5MB
~29K SLoC