#deserialize #serde #no-std

无 std deer

一个后端无关的渐进式反序列化框架

1 个不稳定版本

0.0.0-预留2023年2月16日

#615 in #deserialize

MIT/Apache

14KB

deer

deer 是一个 Rust 的 实验性 后端无关反序列化框架,具有有意义的错误信息和上下文(利用 error-stack),默认具有渐进式失败行为。

⚠️ 声明 ⚠️

此 crate 不包含任何功能,仅作为名称预留,以防止潜在的名字抢占。在未来,实际的 crate 将以这个名字发布,有关当前(不完整)的 crate 实现,请访问链接的仓库。

渐进式失败

目前可用的 Rust 反序列化程序大多是在正确性和速度方面进行开发的。这些是普遍有益的优化,但在某些情况下(例如,当收集面向用户的验证反馈时),Rust 中可用的扩展评估选项相对较少。 deer 通过有意识地权衡可接受的速率来提高这种状况,以便暴露多个错误。

示例

面向最终用户的 API 是 deer 的一个很好的例子。

给定以下示例

#[derive(Debug, serde::Deserialize, deer::Deserialize)]
struct Body {
    u8: u8,
    string: String
}

fn main() {
    let payload = json!({
        "u8": 256,
        "string": null,
        "extra": 1
    });

    // Note: Syntax is not final!
    let result = deer::json::from_value::<Body>(payload);
    let error = result.expect_err("should fail");
    println!("{error:?}");

    let result = serde_json::from_value::<Body>(payload);
    let error = result.expect_err("should fail");
    println!("{error:?}");
}

serde 一旦遇到 256 大于 u8 所允许的范围,就会立即失败。这会导致 API 消费者感到沮丧,因为他们一旦修复这个问题,下一个问题(即 string 不能为空)就会被返回。 serde 也不包含有关问题所在位置的路径信息,而 deer 则包含这些信息!

deer 通过返回所有现有问题来解决这个问题。这意味着,对于给定的有效载荷进行单个 API 调用将导致以下错误: 256 大于 u8::MAXnull is not String,以及 extra key "extra" provided

这意味着 deer 可以在反序列化时实现自定义验证,同时仍然能够返回所有验证问题。

deer 可能会在未来提供一种方式来描述这些约束。

限制

deer 目前 自己解析值,而是依赖于外部解析器,如 serde_json,这意味着解析将是快速失败的,而 deer 只接触语法正确的值。

未来计划

《deer》的第一个版本故意保持最小化,旨在为未来扩展功能奠定良好基础。有许多可能的未来方向和想法,我们正在尝试看看它们是否能够惠及不同的用例。

内省支持

目前,像serde这样的流行crate不提供内省输出的方法。其他工具试图通过手动解释这些crate的指令来填补这一空白。这通常会导致边缘情况,导致预期值与现实之间的不一致。通过显式支持内省的目标是允许其他工具利用它,并围绕它构建抽象,而不是尝试逆向工程。

内省的格式可能看起来如何目前尚不清楚。

验证

目前,为了能够进行验证,必须创建一个新的类型来执行验证步骤。这种额外的样板代码通常是痛点。想法是,通过使用derive宏的组合器来允许进行可选验证。

它可能看起来像什么
#[derive(deer::Deserialize)]
struct Payload {
    #[validate(all(min(12), max(24)))]
    length: u8
}

宽松的反序列化

在严格反序列化类型的同时,人们可能更愿意在反序列化的同时强制转换值(例如,"1"可能被解释为1)。这种行为将是opt-in而不是opt-out,并在derive级别上启用。

具有解析器的反序列化器

deer目前依赖于外部工具(特别是serde)来实现不同格式的解析,这意味着在解析格式错误的输入时我们仍然会快速失败。在未来,deer可能提供一个尝试从解析错误中恢复并提供有意义诊断的解析器。

它可能看起来像什么
{
  "i8": "string"

"deer"级别

deer力求尽可能地可组合和可配置,这意味着所有非核心行为都应该是opt-in,并且裸deer的速度惩罚应该是最小的。在未来,我们可能需要提供额外的配置参数(最大深度、最大错误数等),以允许在速度至关重要的所有用例中进行进一步调整。

贡献者

deer是由Bilal Mahmoud创建的。它与HASH一起开发。作为一个开源项目,我们非常欢迎外部贡献,并已发布了一个贡献指南,概述了过程。如果您有任何问题,请通过我们的Discord服务器与我们联系。您也可以直接在GitHub仓库中报告错误

许可协议

deer在多种开源许可协议下可用。请参阅LICENSE文件以了解您的选项。

无运行时依赖