9 个版本

0.3.1 2019年7月20日
0.3.0 2019年7月10日
0.2.4 2019年6月21日
0.1.1 2019年4月26日

#14 in #validate-json

MIT 许可证

64KB
1.5K SLoC

jsl crates.io

在 docs.rs 上的文档: https://docs.rs/jsl

此包是 JSON Schema Language 的 Rust 实现。您可以使用它来

  1. 验证输入数据是否符合模式
  2. 获取与该输入数据相关的错误列表,或
  3. 在 JSON Schema Language 上构建您自己的自定义工具。

关于 JSON Schema Language

JSON Schema Language ("JSL") 允许您为 JSON 数据或与 JSON 相当的数据(例如 YAML、CBOR、BSON 等的子集)定义模式。使用这些模式,您可以

  1. 验证输入的 JSON 数据是否格式正确
  2. 记录您期望接收或生成的数据类型
  3. 自动生成代码、文档或用户界面
  4. 生成可互操作、详细的验证错误

JSON Schema Language 被设计成让 JSON 更具生产力。因此,它非常轻量且易于实现。它旨在直观且易于扩展以适应您的自定义用例。

更多信息请见: https://json-schema-language.github.io.

用法

在 docs.rs 上的详细文档提供了更多细节,但在此简要说明如何使用此包验证输入数据

use serde_json::json;
use jsl::{Schema, SerdeSchema, Validator, ValidationError};
use failure::Error;
use std::collections::HashSet;

fn main() -> Result<(), Error> {
    let demo_schema_data = r#"
        {
            "properties": {
                "name": { "type": "string" },
                "age": { "type": "number" },
                "phones": {
                    "elements": { "type": "string" }
                }
            }
        }
    "#;

    // The SerdeSchema type is a serde-friendly format for representing
    // schemas.
    let demo_schema: SerdeSchema = serde_json::from_str(demo_schema_data)?;

    // The Schema type is a higher-level format that does more validity
    // checks.
    let demo_schema = Schema::from_serde(demo_schema).unwrap();

    // Validator can quickly check if an instance satisfies some schema.
    // With the new_with_config constructor, you can configure how many
    // errors to return, and how to handle the possibility of a
    // circularly-defined schema.
    let validator = Validator::new();
    let input_ok = json!({
        "name": "John Doe",
        "age": 43,
        "phones": [
            "+44 1234567",
            "+44 2345678"
        ]
    });

    let validation_errors_ok = validator.validate(&demo_schema, &input_ok)?;
    assert!(validation_errors_ok.is_empty());

    let input_bad = json!({
        "age": "43",
        "phones": [
            "+44 1234567",
            442345678
        ]
    });

    // Each ValidationError holds paths to the bad part of the input, as
    // well as the part of the schema which rejected it.
    //
    // For testing purposes, we'll sort the errors so that their order is
    // predictable.
    let mut validation_errors_bad = validator.validate(&demo_schema, &input_bad)?;
    validation_errors_bad.sort_by_key(|err| err.instance_path().to_string());
    assert_eq!(validation_errors_bad.len(), 3);

    // "name" is required
    assert_eq!(validation_errors_bad[0].instance_path().to_string(), "");
    assert_eq!(validation_errors_bad[0].schema_path().to_string(), "/properties/name");

    // "age" has the wrong type
    assert_eq!(validation_errors_bad[1].instance_path().to_string(), "/age");
    assert_eq!(validation_errors_bad[1].schema_path().to_string(), "/properties/age/type");

    // "phones[1]" has the wrong type
    assert_eq!(validation_errors_bad[2].instance_path().to_string(), "/phones/1");
    assert_eq!(validation_errors_bad[2].schema_path().to_string(), "/properties/phones/elements/type");

    Ok(())
}

依赖关系

~1.6–2.6MB
~51K SLoC