6个版本 (破坏性)
0.5.0 | 2024年3月17日 |
---|---|
0.4.1 | 2024年1月30日 |
0.3.0 | 2023年9月5日 |
0.2.0 | 2023年8月6日 |
0.1.0 | 2023年4月22日 |
#142 in 解析器实现
2,144 每月下载量
用于 2 crates
765KB
12K SLoC
Struson是一个符合RFC 8259的流式JSON读取器和写入器。
其主要目的是允许以内存高效的方式写入JSON文档,而无需在内存中存储完整的JSON文档结构。
Struson的API受到了Java库Gson(类JsonReader
和JsonWriter
)的流式API的启发。它是相对底层的,其方法对应于JSON文档的元素,在其之上几乎没有抽象,允许读取和写入任何有效的JSON文档,无论其结构或内容如何。
注意:此库仍然是实验性的。性能还不是很好,API可能会在未来版本中更改;版本 < 1.0.0 可能不会遵循语义版本化,可能会发生破坏性更改。
欢迎反馈和改进建议!
为什么?
最流行的JSON Rust crates Serde JSON (serde_json
)和json-rust (json
)主要提供用于处理JSON的高级API。
-
Serde JSON提供了一个API,用于将JSON转换为类似DOM的结构(模块
serde_json::value
)以及通过将结构体转换为JSON和反之亦然的对象映射功能。两者都需要在内存中存在完整的价值。特例serde_json::ser::Formatter
实际上允许以流式方式写入JSON,但其API可以说是过于底层且不便于使用:您必须自己处理字符串转义,并且必须为每个方法调用提供写入器作为参数。
然而,请注意,Serde JSON的StreamDeserializer
允许以流式方式读取多个顶层值,并且可以通过自定义Visitor
实现来解决某些流式使用案例,请参阅流式化数组和丢弃数据的文档中的示例。 -
json-rust 提供了一个将 JSON 转换为类似 DOM 结构的 API(枚举
json::JsonValue
),这需要完整的值存在于内存中。特质json::codegen::Generator
提供了一个部分 API,用于以流式方式写入 JSON,但它缺少以流式方式写入 JSON 数组和对象的函数。
如果您需要以类似 DOM 的方式处理 JSON,或者需要对象映射功能将结构体转换为 JSON 及其反向转换,那么 Struson 不适合您的用例,您应该使用上述库之一。
主要功能
- 低级流式 API,无隐式值转换
- 严格强制执行正确的 API 使用
- 仅在 API 使用不正确时引发恐慌
格式错误的 JSON 和意外的 JSON 结构只会导致错误 - API 不需要递归处理 JSON 数组和对象
理论上可以读取和写入任意深度嵌套的 JSON 数据 - 以字符串形式读取和写入任意精确的 JSON 数字
(JsonReader::next_number_as_str
和JsonWriter::number_value_from_string
) - 在 JSON 数据中跳转到特定位置(
JsonReader::seek_to
) - 将 JSON 数据从读取器传输到写入器(
JsonReader::transfer_to
) - 读取和写入任意大的 JSON 字符串值
(JsonReader::next_string_reader
和JsonWriter::string_value_writer
) - 可选的 Serde 集成
使用示例
提供了 API 的两种变体
- 简单:确保在编译时正确使用 API
- 高级:仅在运行时(通过引发恐慌)确保正确使用 API;更灵活且提供更多功能
简单 API
🔬 实验
简单 API 及其命名目前处于实验阶段,请在此处提供反馈 here。它必须通过在 Cargo.toml
中指定 experimental
功能来启用
[dependencies]
struson = { version = "...", features = ["experimental"] }
任何反馈都受欢迎!
读取
请参阅 SimpleJsonReader
。
use struson::reader::simple::*;
// In this example JSON data comes from a string;
// normally it would come from a file or a network connection
let json_reader = SimpleJsonReader::new(r#"["a", "short", "example"]"#.as_bytes());
let mut words = Vec::<String>::new();
json_reader.read_array_items(|item_reader| {
let word = item_reader.read_string()?;
words.push(word);
Ok(())
})?;
assert_eq!(words, vec!["a", "short", "example"]);
对于读取嵌套值,可以使用方法 read_seeked
和 read_seeked_multi
use struson::reader::simple::*;
use struson::reader::simple::multi_json_path::multi_json_path;
// In this example JSON data comes from a string;
// normally it would come from a file or a network connection
let json = r#"{
"users": [
{"name": "John", "age": 32},
{"name": "Jane", "age": 41}
]
}"#;
let json_reader = SimpleJsonReader::new(json.as_bytes());
let mut ages = Vec::<u32>::new();
// Select the ages of all users
let json_path = multi_json_path!["users", [*], "age"];
json_reader.read_seeked_multi(&json_path, false, |value_reader| {
let age = value_reader.read_number()??;
ages.push(age);
Ok(())
})?;
assert_eq!(ages, vec![32, 41]);
写入
请参阅 SimpleJsonWriter
。
use struson::writer::simple::*;
// In this example JSON bytes are stored in a Vec;
// normally they would be written to a file or network connection
let mut writer = Vec::<u8>::new();
let json_writer = SimpleJsonWriter::new(&mut writer);
json_writer.write_object(|object_writer| {
object_writer.write_number_member("a", 1)?;
object_writer.write_bool_member("b", true)?;
Ok(())
})?;
let json = String::from_utf8(writer)?;
assert_eq!(json, r#"{"a":1,"b":true}"#);
高级 API
读取
请参阅 JsonStreamReader
。
use struson::reader::*;
// In this example JSON data comes from a string;
// normally it would come from a file or a network connection
let json = r#"{"a": [1, true]}"#;
let mut json_reader = JsonStreamReader::new(json.as_bytes());
json_reader.begin_object()?;
assert_eq!(json_reader.next_name()?, "a");
json_reader.begin_array()?;
assert_eq!(json_reader.next_number::<u32>()??, 1);
assert_eq!(json_reader.next_bool()?, true);
json_reader.end_array()?;
json_reader.end_object()?;
// Ensures that there is no trailing data
json_reader.consume_trailing_whitespace()?;
写入
请参阅 JsonStreamWriter
。
use struson::writer::*;
// In this example JSON bytes are stored in a Vec;
// normally they would be written to a file or network connection
let mut writer = Vec::<u8>::new();
let mut json_writer = JsonStreamWriter::new(&mut writer);
json_writer.begin_object()?;
json_writer.name("a")?;
json_writer.begin_array()?;
json_writer.number_value(1)?;
json_writer.bool_value(true)?;
json_writer.end_array()?;
json_writer.end_object()?;
// Ensures that the JSON document is complete and flushes the buffer
json_writer.finish_document()?;
let json = String::from_utf8(writer)?;
assert_eq!(json, r#"{"a":[1,true]}"#);
Serde 集成
可选与Serde集成,允许将Serialize
写入到JsonWriter
,并从JsonReader
读取Deserialize
。有关更多信息,请参阅此crate的serde
模块链接。
变更日志
请参阅GitHub发行版。
构建
此项目使用cargo-make进行构建
cargo make
如果您不想安装cargo-make,可以手动运行Makefile.toml
中声明的任务。
类似项目
- https://github.com/alexmaco/json_stream
Rust的流式JSON解析器/发射器库
- https://github.com/sarum90/qjsonrs
用Rust编写的JSON标记器
- https://github.com/jeremiah-shaulov/nop-json
JSON序列化和反序列化(全功能、现代、流式、直接到结构体/枚举)
- https://github.com/isagalaev/ijson-rust
Rust重新实现的Python流式JSON解析器ijson
- https://github.com/byron/json-tools
零拷贝json-lexer、过滤器序列化器。
- https://github.com/01mf02/hifijson
高保真JSON解析器和标记器
- https://github.com/khonsulabs/justjson的
justjson::parser::Tokenizer
将JSON源转换为一系列标记的JSON标记器
- https://github.com/iovxw/jsonpull
Json拉取解析器
- rustc-serialize
Parser
(已弃用)一个流式JSON解析器,作为JsonEvent迭代器的迭代器实现,消耗一个字符迭代器。
许可协议
在以下任一许可协议下发布:
由您选择。
您为此项目做出的所有贡献都隐式地受到上述两种许可协议的许可,无需任何附加条款或条件。
注意:此双重许可与大多数Rust项目相同,请参阅Rust API指南。
依赖关系
~0.3–0.9MB
~20K SLoC