Add #[schemars(extend("key" = value))]
attribute (#297)
This commit is contained in:
parent
97b70aa82c
commit
840315b2dd
18 changed files with 527 additions and 26 deletions
|
@ -13,11 +13,11 @@
|
|||
"default": false
|
||||
},
|
||||
"my_optional_string": {
|
||||
"default": null,
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"my_struct2": {
|
||||
"$ref": "#/$defs/MyStruct2",
|
||||
|
|
101
schemars/tests/expected/extend_enum_adjacent.json
Normal file
101
schemars/tests/expected/extend_enum_adjacent.json
Normal file
|
@ -0,0 +1,101 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"title": "Adjacent",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Unit"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"t"
|
||||
],
|
||||
"foo": "bar"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"NewType"
|
||||
]
|
||||
},
|
||||
"c": true
|
||||
},
|
||||
"required": [
|
||||
"t",
|
||||
"c"
|
||||
],
|
||||
"foo": "bar"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Tuple"
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"type": "array",
|
||||
"prefixItems": [
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
],
|
||||
"minItems": 2,
|
||||
"maxItems": 2
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"t",
|
||||
"c"
|
||||
],
|
||||
"foo": "bar"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Struct"
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"i": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"b": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"i",
|
||||
"b"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"t",
|
||||
"c"
|
||||
],
|
||||
"foo": "bar"
|
||||
}
|
||||
],
|
||||
"foo": "bar"
|
||||
}
|
73
schemars/tests/expected/extend_enum_external.json
Normal file
73
schemars/tests/expected/extend_enum_external.json
Normal file
|
@ -0,0 +1,73 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"title": "External",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"const": "Unit",
|
||||
"foo": "bar"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"NewType": true
|
||||
},
|
||||
"required": [
|
||||
"NewType"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"foo": "bar"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Tuple": {
|
||||
"type": "array",
|
||||
"prefixItems": [
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
],
|
||||
"minItems": 2,
|
||||
"maxItems": 2
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Tuple"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"foo": "bar"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Struct": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"i": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"b": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"i",
|
||||
"b"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Struct"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"foo": "bar"
|
||||
}
|
||||
],
|
||||
"foo": "bar"
|
||||
}
|
55
schemars/tests/expected/extend_enum_internal.json
Normal file
55
schemars/tests/expected/extend_enum_internal.json
Normal file
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"title": "Internal",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"const": "Unit"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"typeProperty"
|
||||
],
|
||||
"foo": "bar"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"const": "NewType"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"typeProperty"
|
||||
],
|
||||
"foo": "bar"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"i": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"b": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"const": "Struct"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"typeProperty",
|
||||
"i",
|
||||
"b"
|
||||
],
|
||||
"foo": "bar"
|
||||
}
|
||||
],
|
||||
"foo": "bar"
|
||||
}
|
46
schemars/tests/expected/extend_enum_untagged.json
Normal file
46
schemars/tests/expected/extend_enum_untagged.json
Normal file
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"title": "Untagged",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "null",
|
||||
"foo": "bar"
|
||||
},
|
||||
{
|
||||
"foo": "bar"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"prefixItems": [
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
],
|
||||
"minItems": 2,
|
||||
"maxItems": 2,
|
||||
"foo": "bar"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"i": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"b": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"i",
|
||||
"b"
|
||||
],
|
||||
"foo": "bar"
|
||||
}
|
||||
],
|
||||
"foo": "bar"
|
||||
}
|
27
schemars/tests/expected/extend_struct.json
Normal file
27
schemars/tests/expected/extend_struct.json
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"title": "Struct",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"value": {
|
||||
"foo": "bar"
|
||||
},
|
||||
"int": {
|
||||
"type": "overridden",
|
||||
"format": "int32"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"value",
|
||||
"int"
|
||||
],
|
||||
"msg": "hello world",
|
||||
"obj": {
|
||||
"array": [
|
||||
null,
|
||||
null
|
||||
]
|
||||
},
|
||||
"3": 3.0,
|
||||
"pi": 3.14
|
||||
}
|
|
@ -35,6 +35,8 @@
|
|||
},
|
||||
"my_tuple": {
|
||||
"type": "array",
|
||||
"minItems": 2,
|
||||
"maxItems": 2,
|
||||
"items": [
|
||||
{
|
||||
"type": "string",
|
||||
|
@ -44,9 +46,7 @@
|
|||
{
|
||||
"type": "integer"
|
||||
}
|
||||
],
|
||||
"maxItems": 2,
|
||||
"minItems": 2
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
},
|
||||
"my_tuple": {
|
||||
"type": "array",
|
||||
"minItems": 2,
|
||||
"maxItems": 2,
|
||||
"items": [
|
||||
{
|
||||
"type": "string",
|
||||
|
@ -44,9 +46,7 @@
|
|||
{
|
||||
"type": "integer"
|
||||
}
|
||||
],
|
||||
"maxItems": 2,
|
||||
"minItems": 2
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
},
|
||||
"my_tuple": {
|
||||
"type": "array",
|
||||
"minItems": 2,
|
||||
"maxItems": 2,
|
||||
"items": [
|
||||
{
|
||||
"type": "string",
|
||||
|
@ -46,9 +48,7 @@
|
|||
{
|
||||
"type": "integer"
|
||||
}
|
||||
],
|
||||
"maxItems": 2,
|
||||
"minItems": 2
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"maxItems": 2,
|
||||
"minItems": 2,
|
||||
"items": [
|
||||
{
|
||||
"type": "integer",
|
||||
|
@ -40,9 +42,7 @@
|
|||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
],
|
||||
"minItems": 2,
|
||||
"maxItems": 2
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"maxItems": 2,
|
||||
"minItems": 2,
|
||||
"items": [
|
||||
{
|
||||
"type": "integer",
|
||||
|
@ -35,9 +37,7 @@
|
|||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
],
|
||||
"minItems": 2,
|
||||
"maxItems": 2
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"maxItems": 2,
|
||||
"minItems": 2,
|
||||
"items": [
|
||||
{
|
||||
"type": "integer",
|
||||
|
@ -40,9 +42,7 @@
|
|||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
],
|
||||
"minItems": 2,
|
||||
"maxItems": 2
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
96
schemars/tests/extend.rs
Normal file
96
schemars/tests/extend.rs
Normal file
|
@ -0,0 +1,96 @@
|
|||
mod util;
|
||||
use schemars::JsonSchema;
|
||||
use serde_json::Value;
|
||||
use util::*;
|
||||
|
||||
const THREE: f64 = 3.0;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(JsonSchema)]
|
||||
#[schemars(extend("msg" = concat!("hello ", "world"), "obj" = {"array": [null, ()]}))]
|
||||
#[schemars(extend("3" = THREE), extend("pi" = THREE + 0.14))]
|
||||
struct Struct {
|
||||
#[schemars(extend("foo" = "bar"))]
|
||||
value: Value,
|
||||
#[schemars(extend("type" = "overridden"))]
|
||||
int: i32,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn doc_comments_struct() -> TestResult {
|
||||
test_default_generated_schema::<Struct>("extend_struct")
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(JsonSchema)]
|
||||
#[schemars(extend("foo" = "bar"))]
|
||||
enum External {
|
||||
#[schemars(extend("foo" = "bar"))]
|
||||
Unit,
|
||||
#[schemars(extend("foo" = "bar"))]
|
||||
NewType(Value),
|
||||
#[schemars(extend("foo" = "bar"))]
|
||||
Tuple(i32, bool),
|
||||
#[schemars(extend("foo" = "bar"))]
|
||||
Struct { i: i32, b: bool },
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn doc_comments_enum_external() -> TestResult {
|
||||
test_default_generated_schema::<External>("extend_enum_external")
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(JsonSchema)]
|
||||
#[schemars(tag = "typeProperty", extend("foo" = "bar"))]
|
||||
enum Internal {
|
||||
#[schemars(extend("foo" = "bar"))]
|
||||
Unit,
|
||||
#[schemars(extend("foo" = "bar"))]
|
||||
NewType(Value),
|
||||
#[schemars(extend("foo" = "bar"))]
|
||||
Struct { i: i32, b: bool },
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn doc_comments_enum_internal() -> TestResult {
|
||||
test_default_generated_schema::<Internal>("extend_enum_internal")
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(JsonSchema)]
|
||||
#[schemars(untagged, extend("foo" = "bar"))]
|
||||
enum Untagged {
|
||||
#[schemars(extend("foo" = "bar"))]
|
||||
Unit,
|
||||
#[schemars(extend("foo" = "bar"))]
|
||||
NewType(Value),
|
||||
#[schemars(extend("foo" = "bar"))]
|
||||
Tuple(i32, bool),
|
||||
#[schemars(extend("foo" = "bar"))]
|
||||
Struct { i: i32, b: bool },
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn doc_comments_enum_untagged() -> TestResult {
|
||||
test_default_generated_schema::<Untagged>("extend_enum_untagged")
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(JsonSchema)]
|
||||
#[schemars(tag = "t", content = "c", extend("foo" = "bar"))]
|
||||
enum Adjacent {
|
||||
#[schemars(extend("foo" = "bar"))]
|
||||
Unit,
|
||||
#[schemars(extend("foo" = "bar"))]
|
||||
NewType(Value),
|
||||
#[schemars(extend("foo" = "bar"))]
|
||||
Tuple(i32, bool),
|
||||
#[schemars(extend("foo" = "bar"))]
|
||||
Struct { i: i32, b: bool },
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn doc_comments_enum_adjacent() -> TestResult {
|
||||
test_default_generated_schema::<Adjacent>("extend_enum_adjacent")
|
||||
}
|
11
schemars/tests/ui/invalid_extend.rs
Normal file
11
schemars/tests/ui/invalid_extend.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
use schemars::JsonSchema;
|
||||
|
||||
#[derive(JsonSchema)]
|
||||
#[schemars(extend(x))]
|
||||
#[schemars(extend("x"))]
|
||||
#[schemars(extend("x" = ))]
|
||||
#[schemars(extend("y" = "ok!", "y" = "duplicated!"), extend("y" = "duplicated!"))]
|
||||
#[schemars(extend("y" = "duplicated!"))]
|
||||
pub struct Struct;
|
||||
|
||||
fn main() {}
|
35
schemars/tests/ui/invalid_extend.stderr
Normal file
35
schemars/tests/ui/invalid_extend.stderr
Normal file
|
@ -0,0 +1,35 @@
|
|||
error: expected string literal
|
||||
--> tests/ui/invalid_extend.rs:4:19
|
||||
|
|
||||
4 | #[schemars(extend(x))]
|
||||
| ^
|
||||
|
||||
error: expected `=`
|
||||
--> tests/ui/invalid_extend.rs:5:22
|
||||
|
|
||||
5 | #[schemars(extend("x"))]
|
||||
| ^
|
||||
|
||||
error: Expected extension value
|
||||
--> tests/ui/invalid_extend.rs:6:25
|
||||
|
|
||||
6 | #[schemars(extend("x" = ))]
|
||||
| ^
|
||||
|
||||
error: Duplicate extension key 'y'
|
||||
--> tests/ui/invalid_extend.rs:7:32
|
||||
|
|
||||
7 | #[schemars(extend("y" = "ok!", "y" = "duplicated!"), extend("y" = "duplicated!"))]
|
||||
| ^^^
|
||||
|
||||
error: Duplicate extension key 'y'
|
||||
--> tests/ui/invalid_extend.rs:7:61
|
||||
|
|
||||
7 | #[schemars(extend("y" = "ok!", "y" = "duplicated!"), extend("y" = "duplicated!"))]
|
||||
| ^^^
|
||||
|
||||
error: Duplicate extension key 'y'
|
||||
--> tests/ui/invalid_extend.rs:8:19
|
||||
|
|
||||
8 | #[schemars(extend("y" = "duplicated!"))]
|
||||
| ^^^
|
Loading…
Add table
Add a link
Reference in a new issue