#json-schema #serde #generate-json #macro-derive #document #rust

过程宏 architect-schemars_derive

为 #[derive(JsonSchema)] 提供宏,用于与 schemars 一起使用

3个版本 (1个稳定版)

1.0.0 2023年6月26日
0.8.13 2023年6月14日
0.8.12 2023年6月14日

#38#generate-json

Download history 45/week @ 2024-03-11 37/week @ 2024-03-18 22/week @ 2024-03-25 65/week @ 2024-04-01 35/week @ 2024-04-08 9/week @ 2024-04-15 10/week @ 2024-04-22 9/week @ 2024-04-29 10/week @ 2024-05-06 4/week @ 2024-05-13 16/week @ 2024-05-20 3/week @ 2024-05-27 15/week @ 2024-06-03 14/week @ 2024-06-10 9/week @ 2024-06-17 14/week @ 2024-06-24

每月52次下载
用于 architect-schemars

MIT 协议

87KB
2K SLoC

注意

这是 Architect 对 schemars 的分支。这是 Architect 对 schemars 的分支。这是 Architect 对 schemars 的分支。这是 Architect 对 schemars 的分支。这是 Architect 对 schemars 的分支。这是 Architect 对 schemars 的分支。这是 Architect 对 schemars 的分支。这是 Architect 对 schemars 的分支。这是 Architect 对 schemars 的分支。这是 Architect 对 schemars 的分支。

Schemars

CI Build Crates.io Docs rustc 1.45+

从Rust代码生成JSON Schema文档

基本用法

如果你不关心具体细节,生成你的类型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.fullstack.org.cn/draft-07/schema#",
  "title": "MyStruct",
  "type": "object",
  "required": [
    "my_bool",
    "my_int"
  ],
  "properties": {
    "my_bool": {
      "type": "boolean"
    },
    "my_int": {
      "type": "integer",
      "format": "int32"
    },
    "my_nullable_enum": {
      "anyOf": [
        {
          "$ref": "#/definitions/MyEnum"
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "definitions": {
    "MyEnum": {
      "anyOf": [
        {
          "type": "object",
          "required": [
            "StringNewType"
          ],
          "properties": {
            "StringNewType": {
              "type": "string"
            }
          },
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": [
            "StructVariant"
          ],
          "properties": {
            "StructVariant": {
              "type": "object",
              "required": [
                "floats"
              ],
              "properties": {
                "floats": {
                  "type": "array",
                  "items": {
                    "type": "number",
                    "format": "float"
                  }
                }
              }
            }
          },
          "additionalProperties": false
        }
      ]
    }
  }
}

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.fullstack.org.cn/draft-07/schema#",
  "title": "MyStruct",
  "type": "object",
  "required": [
    "myBool",
    "myNumber"
  ],
  "properties": {
    "myBool": {
      "type": "boolean"
    },
    "myNullableEnum": {
      "default": null,
      "anyOf": [
        {
          "$ref": "#/definitions/MyEnum"
        },
        {
          "type": "null"
        }
      ]
    },
    "myNumber": {
      "type": "integer",
      "format": "int32"
    }
  },
  "additionalProperties": false,
  "definitions": {
    "MyEnum": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "object",
          "required": [
            "floats"
          ],
          "properties": {
            "floats": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "float"
              }
            }
          }
        }
      ]
    }
  }
}

可以使用#[schemars(...)]属性覆盖#[serde(...)]属性,它们的行为相同(例如,#[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": "https://json-schema.fullstack.org.cn/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
  }
}

特性标志

  • derive(默认启用)- 提供了#[derive(JsonSchema)]
  • impl_json_schema - 为Schemars类型本身实现JsonSchema
  • preserve_order - 保持结构体字段在SchemaSchemaObject中的顺序

Schemars可以通过特性标志实现来自几个流行crate的类型上的JsonSchema,启用方式如下(依赖项版本显示在括号内)

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

[dependencies]
schemars = { version = "0.8", features = ["chrono"] }

依赖关系

~1.5MB
~38K SLoC