8 个版本
0.5.1 | 2021 年 1 月 9 日 |
---|---|
0.5.0 | 2021 年 1 月 9 日 |
0.3.1 | 2019 年 8 月 25 日 |
0.2.0 | 2019 年 5 月 17 日 |
0.1.1 | 2019 年 5 月 1 日 |
在 解析器实现 中排名第 1120
每月下载量 215
在 6 个 包中使用
96KB
2.5K SLoC
非结构化文档
此库提供与非结构化数据一起使用的类型。它基于 serde_json 和 serde_value 的功能。根据您的用例,您可能需要使用其中之一。
这些结构用于将数据序列化和反序列化为 serde 的中间容器,并在中间状态中操作这些数据。
目的
那么为什么不使用上述库之一呢?
- serde_json::value::Value 与 JSON 序列化和反序列化紧密耦合。其目的是有一个专门用于 JSON 的中间格式。如果您需要更通用的东西(例如,您需要支持 JSON 不支持的功能),或者不想依赖于 JSON 库,这可能是个问题。文档支持将数据序列化和反序列化为 JSON,而不局限于使用 JSON 库。
- serde_value::Value 提供与文档类似的序列化和反序列化的中间格式,但它不提供像索引和简单类型转换那样操作数据的许多选项。
除了上述库提供的许多功能外,非结构化还提供了
- 与原始类型轻松比较的功能,例如
Document::U64(100) == 100 as u64
- 轻松合并多个文档:
doc1.merge(doc2)
或doc = doc1 + doc2
- 选择器,用于在文档中检索嵌套值而不进行克隆:
doc.select(".path.to.key")
- 从输入文档数组创建新文档的过滤器:
docs.filter("[0].path.to.key | [1].path.to.array[0:5]")
- is_type()、as_type()、take_type()的便捷方法
- 大部分的From实现,以简化文档创建
示例用法
本仓库中主要使用的结构体是Document
。Document提供了易于类型转换和操作的方法。
use unstructured::Document;
use std::collections::BTreeMap;
let mut map = BTreeMap::new(); // Will be inferred as BTreeMap<Document, Document> though root element can be any supported type
map.insert("test".into(), (100 as u64).into()); // From<> is implement for most basic data types
let doc: Document = map.into(); // Create a new Document where the root element is the map defined above
assert_eq!(doc["test"], Document::U64(100));
Document实现了序列化和反序列化,以便在数据格式未知或接收后进行操作时能够轻松使用。
#[macro_use]
extern crate serde;
use unstructured::Document;
#[derive(Deserialize, Serialize)]
struct SomeStruct {
key: String,
}
fn main() {
let from_service = "{\"key\": \"value\"}";
let doc: Document = serde_json::from_str(from_service).unwrap();
let expected: Document = "value".into();
assert_eq!(doc["key"], expected);
let some_struct: SomeStruct = doc.try_into().unwrap();
assert_eq!(some_struct.key, "value");
let another_doc = Document::new(some_struct).unwrap();
assert_eq!(another_doc["key"], expected);
}
可以使用选择器检索嵌套值的引用,而不考虑传入的格式。
- JSON指针语法:
doc.select("/path/to/key")
- 受JQ启发的语法:
doc.select(".path.to.[\"key\"")
use unstructured::Document;
let doc: Document =
serde_json::from_str("{\"some\": {\"nested\": {\"value\": \"is this value\"}}}").unwrap();
let doc_element = doc.select("/some/nested/value").unwrap(); // Returns an Option<Document>, None if not found
let expected: Document = "is this value".into();
assert_eq!(*doc_element, expected);
除了选择器外,还可以使用过滤器从输入文档数组创建新文档。
- 文档选择:"[0]", "[1]", "*"
- 路径导航:"[0].path.to.key" "[0] /path/to/key" r#" [0] .["path"].["to"].["key"] "#
- 索引选择:"[0] .array.[0]"
- 序列选择:"[0] .array.[0:0]" "[0] .array.[:]" "[0] .array.[:5]"
- 过滤多个文档:"[0].key | [1].key"
- 合并文档:"*" "[0].key.to.merge | [1].add.this.key.too | [2].key.to.merge"
use unstructured::Document;
let docs: Vec<Document> = vec![
serde_json::from_str(r#"{"some": {"nested": {"vals": [1,2,3]}}}"#).unwrap(),
serde_json::from_str(r#"{"some": {"nested": {"vals": [4,5,6]}}}"#).unwrap(),
];
let result = Document::filter(&docs, "[0].some.nested.vals | [1].some.nested.vals").unwrap();
assert_eq!(result["some"]["nested"]["vals"][4], Document::U64(5));
依赖项
~0.6–1.7MB
~36K SLoC