5个版本
0.0.5 | 2023年10月13日 |
---|---|
0.0.4 | 2023年9月9日 |
0.0.3 | 2021年5月4日 |
0.0.2 | 2021年3月26日 |
0.0.1 | 2021年3月25日 |
#580 in 数据结构
每月 29 次下载
270KB
7.5K SLoC
🎯 hit
hit
是一个Rust库,用于处理以树状文档结构化的数据,具有以下特性
- H分层
- I索引
- T类型
这个库旨在管理内存中的深度嵌套文档,使用严格类型的数据结构和多个内部链接。这可以表示文字处理文档、目录及其文件和子文件夹以及符号链接...
分层
每个文档都像MongoDB文档一样以文档树的形式组织。这意味着文档总是以一个根 object
开始。在 hit
中,object
被定义为键/值列表。
值可以是
- 简单的(字符串、数字、日期)
- 或者它们可以包含 其他子对象。每个子对象(除了根对象)都可以作为一个 对象 的 属性 来定位。
- 它们也可以包含对其他对象的 引用。
(TODO: 链接到属性类型)
索引
每个 object
都是索引的。这意味着
- 每个对象都必须有一个
_id
,其值为RustString
。 - 每个对象(除了根对象)都可以使用这三个索引来定位
- parent_id
- parent_property
- parent_position
索引允许 hit
提供(TODO: 链接到方法)reference
和 reference_array
类型字段。它们灵感来自关系数据库中的外键,hit
强制一致性规则:只要文档中还有对该对象的引用,就不能删除该对象。
索引还允许您轻松地找到对对象的引用。(TODO: 链接到方法)
类型化
文档中的每个 object
必须有一个(待完善:链接)Model
。模型通过字符串 id 来标识,并在 object
的 type
属性中引用。为了从 ids 解析模型定义,每个 hit
实例都必须初始化一个包含定义的(待完善:链接)Kernel
。
模型
- 列出对象的接受字段名称
- 使用
field types
(待完善:链接)限制接受的值,以及可选的validators
(待完善:链接)
开始使用
hit
是一个 Rust 库。您可以通过将以下行添加到您的 Cargo.toml
文件中来将其添加到您的项目中
TODO
指南:如何创建和使用 hit
实例
创建 hit
实例
要创建一个 hit
数据实例,您需要一个包含模型定义的(待完善:链接)Kernel
。一个核心内核,由我官方支持,是递归设计的(待完善:链接)hit_model
,它允许您为 hit
模型化模型。
为了使其更简单,让我们从基本的、虽然完全无用的(待完善:链接)hit_test_file_model
开始,它表示带链接的目录/文件结构。
我们将使用(待完善:链接)Hit::new_with_values
来创建模型。如果您没有初始值,您也可以使用(待完善:链接)Hit::new
函数。
use hit_file_model::create_kernel;
use hit::{ Hit, ObjectValue, IndexEntryProperty };
use std::collections::HashMap;
// create the kernel
let kernel = create_kernel();
// create a string id for the object
let id = "my_id".into();
// initiate the name value for our root object
let mut values = HashMap::new();
values.insert("name".into(), ObjectValue::String("name".into()));
// we can now create the hit instance
let hit_instance = Hit::new_with_values(
id,
kernel,
values,
// you must specify the main model name
"file/filesystem"
);
属性类型
hit
允许以下属性类型作为值。该(待完善:链接)ObjectValue
枚举处理此类型系统。
简单值
这些值使用(待完善:链接)Hit::set
值设置。
-
字符串
一个
string
字段接受 RustString
值。 -
数字
一个
number
字段接受 Rustf32
值。 -
布尔值
-
日期
一个
date
字段接受作为 Rusti64
值的时间戳。
复杂值
这些字段只能使用 Hit
结构体中的特定方法进行填充。
-
子对象
一个
sub_object
字段接受一个hit
对象作为值。该字段将是填充它的对象的唯一父对象。 -
子对象数组
一个
sub_object_array
字段接受多个hit
对象作为值。它也将是填充它的对象的唯一可能父对象。 -
引用
一个
reference
字段接受同一根Hit
实例中的另一个对象的引用。它不能设置为无效 ID,同样,如果存在对该对象的引用,则不能从根实例中删除对象。请参阅(待完善:链接)强制验证。 -
引用数组
同样,一个
reference_array
字段接受多个引用。
以下子章节将解释如何使用这些值类型。示例将使用先前创建的 hit_test_file_model
实例。
设置简单/标量值
您可以使用(待补充:链接)Hit::set
方法设置一个简单值。
示例
hit_instance::set(
"my_id".into(),
"name".into(),
ObjectValue::String("my_instance_name".into())
).expect("This should set the root object name");
操作可能会返回错误
- (待补充:链接):
HitError::IDNotFound
如果模型ID不存在 - (待补充:链接):
HitError::PropertyNotFound
如果模型没有指定的属性 - (待补充:链接):
HitError::InvalidDataType
如果模型属性不接受该值
添加对象
您可以使用Hit::insert
方法将子对象添加到现有object
。您需要提供
- 对象的
model_type
,这是内核知道它的ID。 - 新插入对象的
String
ID。 - 您可以在
Hashmap<String, ObjectValue>
中为对象的某些字段提供值 - 对象必须始终有一个父对象:您必须提供一个ID和属性名来插入它
- 您可以通过指定将被插入的对象的ID来在属性的具体位置插入对象。如果不提供ID(在函数调用中使用
None
),则对象将被插入列表的末尾。
示例
hit_instance::insert(
"file/folder".into(),
"id2".into(),
Hashmap::new(),
IndexEntryProperty {
id: "my_id".into(),
property: "folders".into(),
},
None,
).expect("Insertion has failed");
删除对象
引用对象
删除对象引用
指南:验证
hit
为您的数据提供验证。有两种验证级别
强制验证
有一些基本的数据完整性规则,hit
模型将不允许您违反这些规则。当您设置值或执行操作时,如果您的操作违反了这些规则,则操作将返回错误。hit
旨在具有最小数量的这些错误。这些错误包括
- 引用完整性。如果您尝试引用不存在的对象ID,或删除在其他字段中被引用的对象,则您的操作将不会执行。
- 数据类型。如果您将字段设置为不接受其
FieldType
的ObjectValue
,则您的操作将被拒绝。 - 对象模型名称。如果您尝试插入具有无效模型名称的对象,则您的操作将被拒绝。
- 对象字段名称。如果您尝试设置对象模型上不存在的属性,或创建具有无效属性名称的对象。
(待补充): 能够向模型添加强制验证。
非阻塞验证
主要的验证模型是非阻塞:这意味着您可以为对象的属性分配无效值。
持久化hit
数据
JSON导入/导出
HitImporter/Exporter:创建自己的序列化/反序列化器
插件/事件处理器
待补充:编写本章内容
指南:创建模型
hit
依赖于模型。类似于SQL表定义,模型是Model
结构的实例。一个Hit
实例依赖于一个Kernel
,它是一组模型(以及稍后我们将看到的插件)。由于Hit
实例具有分层、树状结构,它必须有一个根对象,该对象与其所有子对象一样,都由一个Model
结构来组织。
在我们的(TODO:链接到GitHub)hit_test_file_model
示例中,file/filesystem
模型是根对象,包含文件和文件夹子对象。
在该指南部分,我们将介绍如何创建自己的内核、模型以及插件。
模型定义
model
具有以下属性
-
名称
-
定义 这是一个键/值字典。定义是一个实现
ModelField
特质的struct。您可以编写自己的模型字段,但hit
提供了标准字段,这些字段与上一章中定义的类型非常明显地匹配- (TODO:链接)字符串
- (TODO:链接)整数
- (TODO:链接)浮点数
- (TODO:链接)日期
- (TODO:链接)子对象
- (TODO:链接)子对象数组
- (TODO:链接)引用
- (TODO:链接)引用数组
模型宏
验证器
字段验证器
对象验证器
标准库
创建自定义字段类型
内核
内核宏
TODO:创建宏^^
TODO:稳定化
- 编写指南
- 编写Rust文档
- 测试字段结构?
- 引用数组的验证
- 测试删除包含其他对象的对象
TODO:稳定化后
- 明确API
- 字符串类型依赖的枚举=>
- 提供方法,以便您不需要使用LinkedHashMap来使用hit
TODO:较低优先级
- 使用Rust枚举进行修改
- 重构带有allows_model的move函数
- 实现ACID事务?
- 在Hit中集成model_type索引
- 使用强类型但可扩展的错误进行验证?如何做到这一点?
依赖
~3–4.5MB
~80K SLoC