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

Download history 150/week @ 2024-03-13 110/week @ 2024-03-20 64/week @ 2024-03-27 605/week @ 2024-04-03 160/week @ 2024-04-10 166/week @ 2024-04-17 86/week @ 2024-04-24 121/week @ 2024-05-01 118/week @ 2024-05-08 49/week @ 2024-05-15 64/week @ 2024-05-22 66/week @ 2024-05-29 54/week @ 2024-06-05 61/week @ 2024-06-12 48/week @ 2024-06-19 43/week @ 2024-06-26

每月下载量 215
6 个 包中使用

MIT 许可证

96KB
2.5K SLoC

Crate Documentation MIT License

非结构化文档

此库提供与非结构化数据一起使用的类型。它基于 serde_jsonserde_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