Define Schema as a newtype around serde_json::Value (#289)

This commit is contained in:
Graham Esau 2024-05-12 19:23:54 +01:00 committed by GitHub
parent 7f6a7b7e32
commit 342cd5fd09
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
79 changed files with 1410 additions and 2394 deletions

View file

@ -1,16 +1,6 @@
mod util;
use util::*;
#[test]
fn arrayvec05() -> TestResult {
test_default_generated_schema::<arrayvec05::ArrayVec<[i32; 16]>>("arrayvec")
}
#[test]
fn arrayvec05_string() -> TestResult {
test_default_generated_schema::<arrayvec05::ArrayString<[u8; 16]>>("arrayvec_string")
}
#[test]
fn arrayvec07() -> TestResult {
test_default_generated_schema::<arrayvec07::ArrayVec<i32, 16>>("arrayvec")

View file

@ -1,5 +1,5 @@
mod util;
use bytes::{Bytes, BytesMut};
use bytes1::{Bytes, BytesMut};
use util::*;
#[test]

View file

@ -1,5 +1,5 @@
mod util;
use chrono::prelude::*;
use chrono04::prelude::*;
use schemars::JsonSchema;
use util::*;

View file

@ -3,12 +3,7 @@ use util::*;
#[test]
fn rust_decimal() -> TestResult {
test_default_generated_schema::<rust_decimal::Decimal>("rust_decimal")
}
#[test]
fn bigdecimal03() -> TestResult {
test_default_generated_schema::<bigdecimal03::BigDecimal>("bigdecimal03")
test_default_generated_schema::<rust_decimal1::Decimal>("rust_decimal")
}
#[test]

View file

@ -1,23 +0,0 @@
use schemars::{gen::SchemaGenerator, JsonSchema};
use std::ptr;
#[allow(dead_code)]
#[derive(JsonSchema)]
struct Struct {
foo: i32,
bar: bool,
}
#[test]
fn dereference_struct() {
let mut gen = SchemaGenerator::default();
let struct_ref_schema = gen.subschema_for::<Struct>();
let struct_schema = gen.definitions().get(&<Struct>::schema_name()).unwrap();
assert!(struct_ref_schema.is_ref());
assert!(!struct_schema.is_ref());
let dereferenced = gen.dereference(&struct_ref_schema);
assert!(dereferenced.is_some());
assert!(ptr::eq(dereferenced.unwrap(), struct_schema));
}

View file

@ -1,5 +1,5 @@
mod util;
use either::Either;
use either1::Either;
use util::*;
#[test]

View file

@ -1,5 +1,7 @@
mod util;
use schemars::{JsonSchema, Map};
use std::collections::BTreeMap;
use schemars::JsonSchema;
use util::*;
// Ensure that schemars_derive uses the full path to std::string::String
@ -20,7 +22,7 @@ struct Struct {
#[schemars(rename_all = "camelCase")]
enum External {
UnitOne,
StringMap(Map<&'static str, &'static str>),
StringMap(BTreeMap<&'static str, &'static str>),
UnitStructNewType(UnitStruct),
StructNewType(Struct),
Struct {
@ -29,6 +31,7 @@ enum External {
},
UnitTwo,
Tuple(i32, bool),
// FIXME this should probably only replace the "payload" of the enum
#[schemars(with = "i32")]
WithInt,
}
@ -43,7 +46,7 @@ fn enum_external_tag() -> TestResult {
#[schemars(tag = "typeProperty")]
enum Internal {
UnitOne,
StringMap(Map<&'static str, &'static str>),
StringMap(BTreeMap<&'static str, &'static str>),
UnitStructNewType(UnitStruct),
StructNewType(Struct),
Struct {
@ -51,6 +54,7 @@ enum Internal {
bar: bool,
},
UnitTwo,
// FIXME this should probably only replace the "payload" of the enum
#[schemars(with = "i32")]
WithInt,
}
@ -65,7 +69,7 @@ fn enum_internal_tag() -> TestResult {
#[schemars(untagged)]
enum Untagged {
UnitOne,
StringMap(Map<&'static str, &'static str>),
StringMap(BTreeMap<&'static str, &'static str>),
UnitStructNewType(UnitStruct),
StructNewType(Struct),
Struct {
@ -73,6 +77,7 @@ enum Untagged {
bar: bool,
},
Tuple(i32, bool),
// FIXME this should probably only replace the "payload" of the enum
#[schemars(with = "i32")]
WithInt,
}
@ -87,7 +92,7 @@ fn enum_untagged() -> TestResult {
#[schemars(tag = "t", content = "c")]
enum Adjacent {
UnitOne,
StringMap(Map<&'static str, &'static str>),
StringMap(BTreeMap<&'static str, &'static str>),
UnitStructNewType(UnitStruct),
StructNewType(Struct),
Struct {
@ -96,6 +101,7 @@ enum Adjacent {
},
Tuple(i32, bool),
UnitTwo,
// FIXME this should probably only replace the "payload" of the enum
#[schemars(with = "i32")]
WithInt,
}

View file

@ -1,5 +1,7 @@
mod util;
use schemars::{JsonSchema, Map};
use std::collections::BTreeMap;
use schemars::JsonSchema;
use util::*;
// Ensure that schemars_derive uses the full path to std::string::String
@ -22,7 +24,7 @@ struct Struct {
#[schemars(rename_all = "camelCase", deny_unknown_fields)]
enum External {
UnitOne,
StringMap(Map<&'static str, &'static str>),
StringMap(BTreeMap<&'static str, &'static str>),
UnitStructNewType(UnitStruct),
StructNewType(Struct),
Struct {
@ -31,6 +33,7 @@ enum External {
},
UnitTwo,
Tuple(i32, bool),
// FIXME this should probably only replace the "payload" of the enum
#[schemars(with = "i32")]
WithInt,
}
@ -46,7 +49,7 @@ fn enum_external_tag() -> TestResult {
#[schemars(tag = "typeProperty", deny_unknown_fields)]
enum Internal {
UnitOne,
StringMap(Map<&'static str, &'static str>),
StringMap(BTreeMap<&'static str, &'static str>),
UnitStructNewType(UnitStruct),
StructNewType(Struct),
Struct {
@ -54,6 +57,7 @@ enum Internal {
bar: bool,
},
UnitTwo,
// FIXME this should only replace the "payload" of the enum (which doesn't even make sense for unit enums!)
#[schemars(with = "i32")]
WithInt,
}
@ -69,7 +73,7 @@ fn enum_internal_tag() -> TestResult {
#[schemars(untagged, deny_unknown_fields)]
enum Untagged {
UnitOne,
StringMap(Map<&'static str, &'static str>),
StringMap(BTreeMap<&'static str, &'static str>),
UnitStructNewType(UnitStruct),
StructNewType(Struct),
Struct {
@ -77,6 +81,7 @@ enum Untagged {
bar: bool,
},
Tuple(i32, bool),
// FIXME this should probably only replace the "payload" of the enum
#[schemars(with = "i32")]
WithInt,
}
@ -92,7 +97,7 @@ fn enum_untagged() -> TestResult {
#[schemars(tag = "t", content = "c", deny_unknown_fields)]
enum Adjacent {
UnitOne,
StringMap(Map<&'static str, &'static str>),
StringMap(BTreeMap<&'static str, &'static str>),
UnitStructNewType(UnitStruct),
StructNewType(Struct),
Struct {
@ -101,6 +106,7 @@ enum Adjacent {
},
Tuple(i32, bool),
UnitTwo,
// FIXME this should probably only replace the "payload" of the enum
#[schemars(with = "i32")]
WithInt,
}

View file

@ -1,8 +1,11 @@
mod util;
use enumset::{EnumSet, EnumSetType};
use enumset1::{EnumSet, EnumSetType};
use schemars::JsonSchema;
use util::*;
// needed to derive EnumSetType when using a crate alias
extern crate enumset1 as enumset;
#[derive(EnumSetType, JsonSchema)]
enum Foo {
Bar,

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "String",
"title": "string",
"type": "string"
}

View file

@ -1,6 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Decimal",
"type": "string",
"pattern": "^-?[0-9]+(\\.[0-9]+)?$"
}

View file

@ -1,6 +1,6 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Either_int32_or_Either_Boolean_or_Null",
"title": "Either_int32_or_Either_boolean_or_null",
"anyOf": [
{
"type": "integer",

View file

@ -127,8 +127,7 @@
"WithInt"
]
}
},
"additionalProperties": false
}
}
]
}

View file

@ -15,7 +15,7 @@
"$ref": "#/definitions/Range_of_double"
},
"bound": {
"$ref": "#/definitions/Bound_of_String"
"$ref": "#/definitions/Bound_of_string"
}
},
"definitions": {
@ -55,7 +55,7 @@
}
}
},
"Bound_of_String": {
"Bound_of_string": {
"oneOf": [
{
"type": "object",

View file

@ -10,10 +10,10 @@
],
"properties": {
"byte_or_bool2": {
"$ref": "#/definitions/Or_for_uint8_and_Boolean"
"$ref": "#/definitions/Or_for_uint8_and_boolean"
},
"unit_or_t2": {
"$ref": "#/definitions/Or_for_Null_and_int32"
"$ref": "#/definitions/Or_for_null_and_int32"
},
"s": {
"$ref": "#/definitions/Str"
@ -30,7 +30,7 @@
}
},
"definitions": {
"Or_for_uint8_and_Boolean": {
"Or_for_uint8_and_boolean": {
"anyOf": [
{
"type": "integer",
@ -42,7 +42,7 @@
}
]
},
"Or_for_Null_and_int32": {
"Or_for_null_and_int32": {
"anyOf": [
{
"type": "null"

View file

@ -8,14 +8,14 @@
],
"properties": {
"result1": {
"$ref": "#/definitions/Result_of_MyStruct_or_Array_of_String"
"$ref": "#/definitions/Result_of_MyStruct_or_Array_of_string"
},
"result2": {
"$ref": "#/definitions/Result_of_Boolean_or_Null"
"$ref": "#/definitions/Result_of_boolean_or_null"
}
},
"definitions": {
"Result_of_MyStruct_or_Array_of_String": {
"Result_of_MyStruct_or_Array_of_string": {
"oneOf": [
{
"type": "object",
@ -56,7 +56,7 @@
}
}
},
"Result_of_Boolean_or_Null": {
"Result_of_boolean_or_null": {
"oneOf": [
{
"type": "object",

View file

@ -1,6 +1,6 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "a-new-name-Array_of_String-int32-int32",
"title": "a-new-name-Array_of_string-int32-int32",
"type": "object",
"required": [
"inner",

View file

@ -1,15 +1,11 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "MyStruct_for_int32_and_Null_and_Boolean_and_Array_of_String",
"title": "MyStruct_for_int32_and_null_and_boolean_and_Array_of_string",
"type": "object",
"required": [
"inner",
"t",
"u",
"v",
"w"
],
"properties": {
"inner": {
"$ref": "#/definitions/MySimpleStruct"
},
"t": {
"type": "integer",
"format": "int32"
@ -25,23 +21,27 @@
"items": {
"type": "string"
}
},
"inner": {
"$ref": "#/definitions/MySimpleStruct"
}
},
"required": [
"inner",
"t",
"u",
"v",
"w"
],
"definitions": {
"MySimpleStruct": {
"type": "object",
"required": [
"foo"
],
"properties": {
"foo": {
"type": "integer",
"format": "int32"
}
}
},
"required": [
"foo"
]
}
}
}

View file

@ -1,6 +1,6 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "MixedGenericStruct_for_MyStruct_for_int32_and_Null_and_Boolean_and_Array_of_String_and_42_and_z",
"title": "MixedGenericStruct_for_MyStruct_for_int32_and_null_and_boolean_and_Array_of_string_and_42_and_z",
"type": "object",
"required": [
"foo",
@ -12,7 +12,7 @@
"format": "int32"
},
"generic": {
"$ref": "#/definitions/MyStruct_for_int32_and_Null_and_Boolean_and_Array_of_String"
"$ref": "#/definitions/MyStruct_for_int32_and_null_and_boolean_and_Array_of_string"
}
},
"definitions": {
@ -28,7 +28,7 @@
}
}
},
"MyStruct_for_int32_and_Null_and_Boolean_and_Array_of_String": {
"MyStruct_for_int32_and_null_and_boolean_and_Array_of_string": {
"type": "object",
"required": [
"inner",

View file

@ -22,8 +22,8 @@
},
{
"type": [
"boolean",
"object"
"object",
"boolean"
],
"required": [
"typeProperty"
@ -39,8 +39,8 @@
},
{
"type": [
"boolean",
"object"
"object",
"boolean"
],
"required": [
"typeProperty"

View file

@ -1,6 +1,6 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Array_of_String",
"title": "Array_of_string",
"type": "array",
"items": {
"type": "string"

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "String",
"title": "string",
"type": "string"
}

View file

@ -1,13 +1,15 @@
mod util;
use indexmap::{IndexMap, IndexSet};
use std::hash::RandomState;
use indexmap2::{IndexMap, IndexSet};
use schemars::JsonSchema;
use util::*;
#[allow(dead_code)]
#[derive(JsonSchema)]
struct IndexMapTypes {
map: IndexMap<i32, bool>,
set: IndexSet<isize>,
map: IndexMap<i32, bool, RandomState>,
set: IndexSet<isize, RandomState>,
}
#[test]

View file

@ -1,16 +0,0 @@
mod util;
use indexmap2::{IndexMap, IndexSet};
use schemars::JsonSchema;
use util::*;
#[allow(dead_code)]
#[derive(JsonSchema)]
struct IndexMapTypes {
map: IndexMap<i32, bool>,
set: IndexSet<isize>,
}
#[test]
fn indexmap_types() -> TestResult {
test_default_generated_schema::<IndexMapTypes>("indexmap")
}

View file

@ -1,19 +0,0 @@
mod util;
use schemars::gen::SchemaSettings;
use schemars::schema::RootSchema;
use util::*;
#[test]
fn schema_matches_draft07() -> TestResult {
test_generated_schema::<RootSchema>("schema", SchemaSettings::draft07())
}
#[test]
fn schema_matches_2019_09() -> TestResult {
test_generated_schema::<RootSchema>("schema-2019_09", SchemaSettings::draft2019_09())
}
#[test]
fn schema_matches_openapi3() -> TestResult {
test_generated_schema::<RootSchema>("schema-openapi3", SchemaSettings::openapi3())
}

View file

@ -2,7 +2,7 @@ mod util;
use schemars::JsonSchema;
use util::*;
fn schema_fn(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
fn schema_fn(gen: &mut schemars::gen::SchemaGenerator) -> schemars::Schema {
<bool>::json_schema(gen)
}
@ -21,6 +21,7 @@ pub enum External {
#[schemars(schema_with = "schema_fn")] DoesntImplementJsonSchema,
i32,
),
// FIXME this should probably only replace the "payload" of the enum
#[schemars(schema_with = "schema_fn")]
Unit,
}
@ -38,6 +39,7 @@ pub enum Internal {
foo: DoesntImplementJsonSchema,
},
NewType(#[schemars(schema_with = "schema_fn")] DoesntImplementJsonSchema),
// FIXME this should probably only replace the "payload" of the enum
#[schemars(schema_with = "schema_fn")]
Unit,
}
@ -59,6 +61,7 @@ pub enum Untagged {
#[schemars(schema_with = "schema_fn")] DoesntImplementJsonSchema,
i32,
),
// FIXME this should probably only replace the "payload" of the enum
#[schemars(schema_with = "schema_fn")]
Unit,
}
@ -80,6 +83,7 @@ pub enum Adjacent {
#[schemars(schema_with = "schema_fn")] DoesntImplementJsonSchema,
i32,
),
// FIXME this should probably only replace the "payload" of the enum
#[schemars(schema_with = "schema_fn")]
Unit,
}

View file

@ -2,7 +2,7 @@ mod util;
use schemars::JsonSchema;
use util::*;
fn schema_fn(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
fn schema_fn(gen: &mut schemars::gen::SchemaGenerator) -> schemars::Schema {
<bool>::json_schema(gen)
}

View file

@ -1,6 +1,6 @@
mod util;
use schemars::JsonSchema;
use semver::Version;
use semver1::Version;
use util::*;
#[allow(dead_code)]

View file

@ -1,5 +1,5 @@
mod util;
use smallvec::SmallVec;
use smallvec1::SmallVec;
use util::*;
#[test]

View file

@ -1,5 +1,5 @@
mod util;
use smol_str::SmolStr;
use smol_str02::SmolStr;
use util::*;
#[test]

View file

@ -1,6 +1,6 @@
mod util;
use schemars::JsonSchema;
use url::Url;
use url2::Url;
use util::*;
#[allow(dead_code)]

View file

@ -1,5 +1,6 @@
use pretty_assertions::assert_eq;
use schemars::{gen::SchemaSettings, schema::RootSchema, schema_for, JsonSchema};
use schemars::visit::Visitor;
use schemars::{gen::SchemaSettings, schema_for, JsonSchema, Schema};
use std::error::Error;
use std::fs;
@ -17,7 +18,16 @@ pub fn test_default_generated_schema<T: JsonSchema>(file: &str) -> TestResult {
test_schema(&actual, file)
}
pub fn test_schema(actual: &RootSchema, file: &str) -> TestResult {
pub fn test_schema(actual: &Schema, file: &str) -> TestResult {
// TEMP for easier comparison of schemas handling changes that don't actually affect a schema:
// - `required` ordering has changed
// - previously `f64` properties may now be integers
let actual = &{
let mut actual = actual.clone();
TempFixupForTests.visit_schema(&mut actual);
actual
};
let expected_json = match fs::read_to_string(format!("tests/expected/{}.json", file)) {
Ok(j) => j,
Err(e) => {
@ -35,8 +45,30 @@ pub fn test_schema(actual: &RootSchema, file: &str) -> TestResult {
Ok(())
}
fn write_actual_to_file(schema: &RootSchema, file: &str) -> TestResult {
fn write_actual_to_file(schema: &Schema, file: &str) -> TestResult {
let actual_json = serde_json::to_string_pretty(&schema)?;
fs::write(format!("tests/actual/{}.json", file), actual_json)?;
Ok(())
}
struct TempFixupForTests;
impl schemars::visit::Visitor for TempFixupForTests {
fn visit_schema(&mut self, schema: &mut Schema) {
schemars::visit::visit_schema(self, schema);
if let Some(object) = schema.as_object_mut() {
if let Some(serde_json::Value::Array(required)) = object.get_mut("required") {
required.sort_unstable_by(|a, b| a.as_str().cmp(&b.as_str()));
}
for (key, value) in object {
if key == "multipleOf" || key.ends_with("aximum") || key.ends_with("inimum") {
if let Some(f) = value.as_f64() {
*value = f.into();
}
}
}
}
}
}

View file

@ -1,11 +1,6 @@
mod util;
use util::*;
#[test]
fn uuid08() -> TestResult {
test_default_generated_schema::<uuid08::Uuid>("uuid")
}
#[test]
fn uuid1() -> TestResult {
test_default_generated_schema::<uuid1::Uuid>("uuid")