#验证 #序列化 #反序列化 #二进制数据 #二进制格式 #二进制编码

fog-pack

支持不可变引用、模式和压缩的二进制数据格式

10 个不稳定版本 (4 个破坏性更改)

0.5.0 2023年8月27日
0.4.2 2023年8月5日
0.4.0 2023年7月28日
0.3.0 2023年7月12日
0.1.1 2020年5月29日

#826 in 编码

Download history 15/week @ 2024-03-08 7/week @ 2024-03-15 42/week @ 2024-03-29 16/week @ 2024-04-05

123 每月下载量
3 crates 中使用

MIT/Apache

670KB
14K SLoC

fog-pack

License Cargo Documentation

一个用于内容寻址、去中心化存储的序列化库。

雾包序列化格式是从头开始设计的,旨在有效地用于内容寻址存储系统,并在去中心化网络中有效工作。鉴于这些是格式最高的优先级,它不得不做出一些其他序列化格式不会做出的艰难选择。以下是简要概述

  • 它是一种自描述的二进制序列化格式
  • 它基于 serde 对 Rust 结构的序列化
  • 它对所有数据都有一个规范形式。相同的数据将只有一个有效的序列化版本。
  • 它支持用于验证序列化数据的数据模式
  • 数据模式可以序列化
  • 数据可以封装到文档中,这些文档可以标记为符合数据所遵循的数据模式。文档始终具有一个独特的加密哈希,用于标识数据。
  • 数据还可以封装到条目中,这些条目始终与父文档关联,并有一个字符串用于将它们与类似的条目分组。
  • 文档和条目可以 加密签名,这将更改它们的标识哈希。
  • 文档和条目可以 使用 zstandard 压缩,这不会更改它们的标识哈希。当使用数据模式时支持 zstandard 字典。
  • 文档和条目根据设计具有大小限制和有限嵌套深度。
  • 提供了加密对象,使用 fog-crypto 库。

关键概念

  • Schemas: 一个数据模式,它验证文档和相关条目,并且可以压缩它们两者
  • Documents: 一个经过哈希处理的序列化数据块,它可能遵循数据模式并可以进行加密签名。
  • Entries: 一个经过哈希处理的序列化数据块,它具有关联的父文档和键字符串。它还可以进行加密签名。
  • Queries: 一个查询,它可以用来查找附加到文档的条目。

这四种类型构成了 fog-pack 的核心概念,并用于构建内容寻址存储系统中的复杂、相互关联的数据。

那么,在使用中它会是什么样子呢?让我们从一个简单的想法开始:我们想要制作一系列的小文本帖子。这就像是一种博客,所以我们可以有一个作者、博客标题和可选的网站链接。帖子可以作为条目附加到博客上,这些条目将有一个创建时间戳、可选的标题和帖子内容。

我们将首先声明文档和模式

// Our Blog's main document
#[derive(Serialize, Deserialize)]
struct Blog {
    title: String,
    author: String,
    // We prefer to omit the field if it's set to None, which is not serde's default
    #[serde(skip_serializing_if = "Option::is_none")]
    link: Option<String>,
}

// Each post in our blog
#[derive(Serialize, Deserialize)]
struct Post {
    created: Timestamp,
    content: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    title: Option<String>,
}

// Build our schema into a completed schema document.
let schema_doc = SchemaBuilder::new(MapValidator::new()
        .req_add("title", StrValidator::new().build())
        .req_add("author", StrValidator::new().build())
        .opt_add("link", StrValidator::new().build())
        .build()
    )
    .entry_add("post", MapValidator::new()
        .req_add("created", TimeValidator::new().query(true).ord(true).build())
        .opt_add("title", StrValidator::new().query(true).regex(true).build())
        .req_add("content", StrValidator::new().build())
        .build(),
        None
    )
    .build()
    .unwrap();
// For actual use, we'll turn the schema document into a Schema
let schema = Schema::from_doc(&schema_doc)?;

现在我们已经有了模式和结构体,我们可以创建一个新的博客并为其制作帖子。我们将使用加密密钥签名所有内容,这样人们就可以知道是我们在制作这些帖子。我们甚至可以创建一个查询,用于搜索特定的帖子!

// Brand new blog time!
let my_key = fog_crypto::identity::IdentityKey::new();
let my_blog = Blog {
    title: "Rusted Gears: A programming blog".into(),
    author: "ElectricCogs".into(),
    link: Some("https://cognoscan.github.io/".into()),
};
let my_blog = NewDocument::new(my_blog, Some(schema.hash()))?.sign(&my_key)?;
let my_blog = schema.validate_new_doc(my_blog)?;
let blog_hash = my_blog.hash();

// First post!
let new_post = Post {
    created: Timestamp::now();
    title: Some("My first post".into()),
    content: "I'm making my first post using fog-pack!".into(),
};
let new_post = NewEntry::new(new_post, "post", &blog_hash)?.sign(&my_key)?;

// We can find entries using a Query:
let query = NewQuery::new("post", MapValidator::new()
    .req_add("title", StrValidator::new().in_add("My first post").build())
    .build()
);

// To complete serialization of all these structs, we need to pass them through the schema one
// more time:
let (blog_hash, encoded_blog): (Hash, Vec<u8>) =
    schema.encode_doc(my_blog)?;
let (post_hash, encoded_post): (Hash, Vec<u8>) =
    schema.encode_new_entry(new_post)?.complete()?;
let encoded_query =
    schema.encode_query(query)?;

// Decoding is also done via the schema:
let my_blog = schema.decode_doc(encoded_blog)?;
let new_post = schema.decode_entry(encoded_post, "post", &blog_hash)?;
let query = schema.decode_query(encoded_query)?;

许可证

根据您的要求,许可方式可以是以下之一

由您选择。

贡献

除非您明确声明,否则您按照Apache-2.0许可证定义的方式有意提交给作品的所有贡献,将按照上述方式双重许可,没有任何额外的条款或条件。

依赖项

~9–12MB
~240K SLoC