61 个版本

1.0.0-alpha.10 2024 年 8 月 22 日
1.0.0-alpha.22024 年 6 月 5 日
0.8.21 2024 年 5 月 23 日
0.8.16 2023 年 11 月 11 日
0.5.1 2019 年 10 月 30 日

#21编码

Download history 308421/week @ 2024-05-02 314588/week @ 2024-05-09 388642/week @ 2024-05-16 388112/week @ 2024-05-23 404735/week @ 2024-05-30 386197/week @ 2024-06-06 392184/week @ 2024-06-13 392864/week @ 2024-06-20 413432/week @ 2024-06-27 351160/week @ 2024-07-04 384067/week @ 2024-07-11 380762/week @ 2024-07-18 399467/week @ 2024-07-25 396070/week @ 2024-08-01 429991/week @ 2024-08-08 435597/week @ 2024-08-15

1,739,454 每月下载量
用于 2,224 个crate (1,035 直接使用)

MIT 许可证

130KB
2.5K SLoC

Schemars

[!注意] 此分支是 Schemars 当前 v1 alpha 版本的分支,仍在开发中。有关 Schemars 当前稳定版本(v0.8.x)的信息,请参阅 v0 分支

有关从 0.8 迁移到 1.0 的信息,请参阅 迁移指南

CI Build Crates.io Docs MSRV 1.60+

生成 JSON Schema 文档从 Rust 代码

基本用法

如果你不关心具体的细节,为你的类型生成 JSON 架构的最简单方法是对类型使用 #[derive(JsonSchema)] 属性并使用 schema_for! 宏。类型的所有字段也必须实现 JsonSchema - Schemars 为许多标准库类型实现了这一点。

use schemars::{schema_for, JsonSchema};

#[derive(JsonSchema)]
pub struct MyStruct {
    pub my_int: i32,
    pub my_bool: bool,
    pub my_nullable_enum: Option<MyEnum>,
}

#[derive(JsonSchema)]
pub enum MyEnum {
    StringNewType(String),
    StructVariant { floats: Vec<f32> },
}

let schema = schema_for!(MyStruct);
println!("{}", serde_json::to_string_pretty(&schema).unwrap());
点击查看生成的 JSON 架构...
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "MyStruct",
  "type": "object",
  "properties": {
    "my_bool": {
      "type": "boolean"
    },
    "my_int": {
      "type": "integer",
      "format": "int32"
    },
    "my_nullable_enum": {
      "anyOf": [
        {
          "$ref": "#/$defs/MyEnum"
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "required": ["my_int", "my_bool"],
  "$defs": {
    "MyEnum": {
      "oneOf": [
        {
          "type": "object",
          "properties": {
            "StringNewType": {
              "type": "string"
            }
          },
          "additionalProperties": false,
          "required": ["StringNewType"]
        },
        {
          "type": "object",
          "properties": {
            "StructVariant": {
              "type": "object",
              "properties": {
                "floats": {
                  "type": "array",
                  "items": {
                    "type": "number",
                    "format": "float"
                  }
                }
              },
              "required": ["floats"]
            }
          },
          "additionalProperties": false,
          "required": ["StructVariant"]
        }
      ]
    }
  }
}

Serde 兼容性

此库的主要目标之一是与 Serde 兼容。任何生成的架构 都应该serde_json 序列化/反序列化到/从 JSON 的方式相匹配。为了支持这一点,Schemars 将检查派生 JsonSchema 的类型上是否存在任何 #[serde(...)] 属性,并相应地调整生成的架构。

use schemars::{schema_for, JsonSchema};
use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct MyStruct {
    #[serde(rename = "myNumber")]
    pub my_int: i32,
    pub my_bool: bool,
    #[serde(default)]
    pub my_nullable_enum: Option<MyEnum>,
}

#[derive(Deserialize, Serialize, JsonSchema)]
#[serde(untagged)]
pub enum MyEnum {
    StringNewType(String),
    StructVariant { floats: Vec<f32> },
}

let schema = schema_for!(MyStruct);
println!("{}", serde_json::to_string_pretty(&schema).unwrap());
点击查看生成的 JSON 架构...
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "MyStruct",
  "type": "object",
  "properties": {
    "myBool": {
      "type": "boolean"
    },
    "myNullableEnum": {
      "anyOf": [
        {
          "$ref": "#/$defs/MyEnum"
        },
        {
          "type": "null"
        }
      ],
      "default": null
    },
    "myNumber": {
      "type": "integer",
      "format": "int32"
    }
  },
  "additionalProperties": false,
  "required": ["myNumber", "myBool"],
  "$defs": {
    "MyEnum": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "object",
          "properties": {
            "floats": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "float"
              }
            }
          },
          "required": ["floats"]
        }
      ]
    }
  }
}

使用 #[serde(...)] 属性时,可以通过 #[schemars(...)] 属性来覆盖,这两个属性的行为相同(例如:#[schemars(rename_all = "camelCase")])。如果您想更改生成的模式而不影响 Serde 的行为,或者您根本不使用 Serde,这可能会很有用。

示例值中的模式

如果您需要一个无法实现或不实现 JsonSchema 的类型的模式,但实现 serde::Serialize,则可以从该类型的值生成 JSON 模式。然而,这种模式通常不如类型实现 JsonSchema 时精确,特别是当它涉及到枚举时,因为 schemars 不会基于单个变体对枚举的结构做出任何假设。

use schemars::schema_for_value;
use serde::Serialize;

#[derive(Serialize)]
pub struct MyStruct {
    pub my_int: i32,
    pub my_bool: bool,
    pub my_nullable_enum: Option<MyEnum>,
}

#[derive(Serialize)]
pub enum MyEnum {
    StringNewType(String),
    StructVariant { floats: Vec<f32> },
}

let schema = schema_for_value!(MyStruct {
    my_int: 123,
    my_bool: true,
    my_nullable_enum: Some(MyEnum::StringNewType("foo".to_string()))
});
println!("{}", serde_json::to_string_pretty(&schema).unwrap());
点击查看生成的 JSON 架构...
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "MyStruct",
  "examples": [
    {
      "my_bool": true,
      "my_int": 123,
      "my_nullable_enum": {
        "StringNewType": "foo"
      }
    }
  ],
  "type": "object",
  "properties": {
    "my_bool": {
      "type": "boolean"
    },
    "my_int": {
      "type": "integer"
    },
    "my_nullable_enum": true
  }
}

功能标志

  • std(默认启用) - 为 Rust 标准库中的类型实现 JsonSchema(即使在禁用此功能的情况下,JsonSchema 仍会在 corealloc 中的类型上实现)。禁用此功能以在 no_std 环境中使用 schemars。
  • derive(默认启用) - 提供了 #[derive(JsonSchema)]
  • preserve_order - 在 Schema 属性中保留结构体字段的顺序
  • raw_value - 为 serde_json::value::RawValue 实现 JsonSchema(启用 serde_json raw_value 功能)

Schemars 可以通过功能标志为几个流行的 crate 中的类型实现 JsonSchema(依赖项版本显示在括号中)

例如,要实现 JsonSchemachrono 类型上,请在您的 Cargo.toml 中将 schemars 依赖项的作为功能启用,如下所示

[dependencies]
schemars = { version = "1.0.0-alpha.10", features = ["chrono04"] }

依赖项

~0.7–2.8MB
~60K SLoC