From 74974d3e95e24eea2115335f3bf1cb78d56ebcdd Mon Sep 17 00:00:00 2001 From: Graham Esau Date: Mon, 16 May 2022 22:39:48 +0100 Subject: [PATCH] Support uuid v1 and arrayvec 0.7 (#142) --- .github/workflows/ci.yml | 2 +- CHANGELOG.md | 3 ++ README.md | 27 ++++++------ docs/4-features.md | 42 +++++++++---------- schemars/Cargo.toml | 20 ++++++--- .../{arrayvec.rs => arrayvec05.rs} | 2 +- schemars/src/json_schema_impls/arrayvec07.rs | 33 +++++++++++++++ schemars/src/json_schema_impls/mod.rs | 14 ++++--- schemars/src/json_schema_impls/uuid08.rs | 21 ++++++++++ .../json_schema_impls/{uuid.rs => uuid1.rs} | 2 +- schemars/src/lib.rs | 29 +++++++------ schemars/tests/arrayvec.rs | 19 ++++++--- schemars/tests/util/mod.rs | 1 - schemars/tests/uuid.rs | 10 +++-- schemars_derive/Cargo.toml | 4 +- 15 files changed, 157 insertions(+), 72 deletions(-) rename schemars/src/json_schema_impls/{arrayvec.rs => arrayvec05.rs} (95%) create mode 100644 schemars/src/json_schema_impls/arrayvec07.rs create mode 100644 schemars/src/json_schema_impls/uuid08.rs rename schemars/src/json_schema_impls/{uuid.rs => uuid1.rs} (96%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b27b983..adb9afb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: include: - rust: 1.37.0 # exclude ui_test as the output is slightly different in rustc 1.37 - test_features: "--features impl_json_schema,chrono,indexmap,either,uuid,smallvec,arrayvec,enumset" + test_features: "--features impl_json_schema,chrono,indexmap,either,uuid08,smallvec,arrayvec05,enumset" allow_failure: false - rust: stable test_features: "--all-features" diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fd40e9..7415674 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ ### Added: - Support generic default values in `default` attributes (https://github.com/GREsau/schemars/pull/83) - Add missing MIT licence text for usage of code from regex_syntax crate (https://github.com/GREsau/schemars/pull/132) +- Support uuid v1 and arrayvec 0.7 via feature flags `uuid1` and `arrayvec07` (https://github.com/GREsau/schemars/pull/142) + - This also adds `uuid08` and `arrayvec05` feature flags for the previously supported versions of these crates. The existing `uuid` and `arrayvec` flags are still supported for backward-compatibility, but they are **deprecated**. + - Similarly, `indexmap1` feature flag is added, and `indexmap` flag is **deprecated**. ## [0.8.8] - 2021-11-25 ### Added: diff --git a/README.md b/README.md index dbdcf8b..95940cc 100644 --- a/README.md +++ b/README.md @@ -264,19 +264,20 @@ println!("{}", serde_json::to_string_pretty(&schema).unwrap()); - `impl_json_schema` - implements `JsonSchema` for Schemars types themselves - `preserve_order` - keep the order of struct fields in `Schema` and `SchemaObject` -## Optional Dependencies -Schemars can implement `JsonSchema` on types from several popular crates, enabled via optional dependencies (dependency versions are shown in brackets): -- [`chrono`](https://crates.io/crates/chrono) (^0.4) -- [`indexmap`](https://crates.io/crates/indexmap) (^1.2) -- [`either`](https://crates.io/crates/either) (^1.3) -- [`uuid`](https://crates.io/crates/uuid) (^0.8) -- [`smallvec`](https://crates.io/crates/smallvec) (^1.0) -- [`arrayvec`](https://crates.io/crates/arrayvec) (^0.5) -- [`url`](https://crates.io/crates/url) (^2.0) -- [`bytes`](https://crates.io/crates/bytes) (^1.0) -- [`enumset`](https://crates.io/crates/enumset) (^1.0) -- [`rust_decimal`](https://crates.io/crates/rust_decimal) (^1.0) -- [`bigdecimal`](https://crates.io/crates/bigdecimal) (^0.3) +Schemars can implement `JsonSchema` on types from several popular crates, enabled via feature flags (dependency versions are shown in brackets): +- `chrono` - [chrono](https://crates.io/crates/chrono) (^0.4) +- `indexmap1` - [indexmap](https://crates.io/crates/indexmap) (^1.2) +- `either` - [either](https://crates.io/crates/either) (^1.3) +- `uuid08` - [uuid](https://crates.io/crates/uuid) (^0.8) +- `uuid1` - [uuid](https://crates.io/crates/uuid) (^1.0) +- `smallvec` - [smallvec](https://crates.io/crates/smallvec) (^1.0) +- `arrayvec05` - [arrayvec](https://crates.io/crates/arrayvec) (^0.5) +- `arrayvec07` - [arrayvec](https://crates.io/crates/arrayvec) (^0.7) +- `url` - [url](https://crates.io/crates/url) (^2.0) +- `bytes` - [bytes](https://crates.io/crates/bytes) (^1.0) +- `enumset` - [enumset](https://crates.io/crates/enumset) (^1.0) +- `rust_decimal` - [rust_decimal](https://crates.io/crates/rust_decimal) (^1.0) +- `bigdecimal` - [bigdecimal](https://crates.io/crates/bigdecimal) (^0.3) For example, to implement `JsonSchema` on types from `chrono`, enable it as a feature in the `schemars` dependency in your `Cargo.toml` like so: diff --git a/docs/4-features.md b/docs/4-features.md index a6aee04..4f848c8 100644 --- a/docs/4-features.md +++ b/docs/4-features.md @@ -6,28 +6,28 @@ permalink: /features/ --- # Feature Flags and Optional Dependencies - -Some functionality can be selectively enabled/disabled via [Cargo features](https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section). These can be enabled when you add Schemars to your crate's cargo.toml, e.g. -```toml -[dependencies] -schemars = { version = "0.6", features = ["chrono"] } -``` - -## Feature Flags - `derive` (enabled by default) - provides `#[derive(JsonSchema)]` macro - `impl_json_schema` - implements `JsonSchema` for Schemars types themselves - `preserve_order` - keep the order of struct fields in `Schema` and `SchemaObject` -## Optional Dependencies -Schemars can implement `JsonSchema` on types from several popular crates, enabled via optional dependencies (dependency versions are shown in brackets): -- [`chrono`](https://crates.io/crates/chrono) (^0.4) -- [`indexmap`](https://crates.io/crates/indexmap) (^1.2) -- [`either`](https://crates.io/crates/either) (^1.3) -- [`uuid`](https://crates.io/crates/uuid) (^0.8) -- [`smallvec`](https://crates.io/crates/smallvec) (^1.0) -- [`arrayvec`](https://crates.io/crates/arrayvec) (^0.5) -- [`url`](https://crates.io/crates/url) (^2.0) -- [`bytes`](https://crates.io/crates/bytes) (^1.0) -- [`enumset`](https://crates.io/crates/enumset) (^1.0) -- [`rust_decimal`](https://crates.io/crates/rust_decimal) (^1.0) -- [`bigdecimal`](https://crates.io/crates/bigdecimal) (^0.3) +Schemars can implement `JsonSchema` on types from several popular crates, enabled via feature flags (dependency versions are shown in brackets): +- `chrono` - [chrono](https://crates.io/crates/chrono) (^0.4) +- `indexmap1` - [indexmap](https://crates.io/crates/indexmap) (^1.2) +- `either` - [either](https://crates.io/crates/either) (^1.3) +- `uuid08` - [uuid](https://crates.io/crates/uuid) (^0.8) +- `uuid1` - [uuid](https://crates.io/crates/uuid) (^1.0) +- `smallvec` - [smallvec](https://crates.io/crates/smallvec) (^1.0) +- `arrayvec05` - [arrayvec](https://crates.io/crates/arrayvec) (^0.5) +- `arrayvec07` - [arrayvec](https://crates.io/crates/arrayvec) (^0.7) +- `url` - [url](https://crates.io/crates/url) (^2.0) +- `bytes` - [bytes](https://crates.io/crates/bytes) (^1.0) +- `enumset` - [enumset](https://crates.io/crates/enumset) (^1.0) +- `rust_decimal` - [rust_decimal](https://crates.io/crates/rust_decimal) (^1.0) +- `bigdecimal` - [bigdecimal](https://crates.io/crates/bigdecimal) (^0.3) + +For example, to implement `JsonSchema` on types from `chrono`, enable it as a feature in the `schemars` dependency in your `Cargo.toml` like so: + +```toml +[dependencies] +schemars = { version = "0.8", features = ["chrono"] } +``` diff --git a/schemars/Cargo.toml b/schemars/Cargo.toml index bc1097f..3231cd8 100644 --- a/schemars/Cargo.toml +++ b/schemars/Cargo.toml @@ -19,11 +19,13 @@ serde_json = "1.0" dyn-clone = "1.0" chrono = { version = "0.4", default-features = false, optional = true } -indexmap = { version = "1.2", features=["serde-1"], optional = true } +indexmap = { version = "1.2", features = ["serde-1"], optional = true } either = { version = "1.3", default-features = false, optional = true } -uuid = { version = "0.8", default-features = false, optional = true } +uuid08 = { version = "0.8", default-features = false, optional = true, package = "uuid" } +uuid1 = { version = "1.0", default-features = false, optional = true, package = "uuid" } smallvec = { version = "1.0", optional = true } -arrayvec = { version = "0.5", default-features = false, optional = true } +arrayvec05 = { version = "0.5", default-features = false, optional = true, package = "arrayvec" } +arrayvec07 = { version = "0.7", default-features = false, optional = true, package = "arrayvec" } url = { version = "2.0", default-features = false, optional = true } bytes = { version = "1.0", optional = true } rust_decimal = { version = "1", default-features = false, optional = true } @@ -31,7 +33,7 @@ bigdecimal = { version = "0.3", default-features = false, optional = true } enumset = { version = "1.0", optional = true } [dev-dependencies] -pretty_assertions = "0.6.1" +pretty_assertions = "1.2.1" trybuild = "1.0" [features] @@ -48,6 +50,12 @@ impl_json_schema = ["derive"] # derive_json_schema will be removed in a later version derive_json_schema = ["impl_json_schema"] +# `uuid` feature contains `uuid08` only for back-compat - will be changed to include uuid 1.0 instead in a later version +uuid = ["uuid08"] +# `arrayvec` feature without version suffix is included only for back-compat - will be removed in a later version +arrayvec = ["arrayvec05"] +indexmap1 = ["indexmap"] + ui_test = [] [[test]] @@ -64,7 +72,7 @@ required-features = ["either"] [[test]] name = "uuid" -required-features = ["uuid"] +required-features = ["uuid08", "uuid1"] [[test]] name = "smallvec" @@ -76,7 +84,7 @@ required-features = ["bytes"] [[test]] name = "arrayvec" -required-features = ["arrayvec"] +required-features = ["arrayvec05", "arrayvec07"] [[test]] name = "schema_for_schema" diff --git a/schemars/src/json_schema_impls/arrayvec.rs b/schemars/src/json_schema_impls/arrayvec05.rs similarity index 95% rename from schemars/src/json_schema_impls/arrayvec.rs rename to schemars/src/json_schema_impls/arrayvec05.rs index 047e3d0..281bde7 100644 --- a/schemars/src/json_schema_impls/arrayvec.rs +++ b/schemars/src/json_schema_impls/arrayvec05.rs @@ -1,7 +1,7 @@ use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; -use arrayvec::{Array, ArrayString, ArrayVec}; +use arrayvec05::{Array, ArrayString, ArrayVec}; use std::convert::TryInto; // Do not set maxLength on the schema as that describes length in characters, but we only diff --git a/schemars/src/json_schema_impls/arrayvec07.rs b/schemars/src/json_schema_impls/arrayvec07.rs new file mode 100644 index 0000000..e2d92c5 --- /dev/null +++ b/schemars/src/json_schema_impls/arrayvec07.rs @@ -0,0 +1,33 @@ +use crate::gen::SchemaGenerator; +use crate::schema::*; +use crate::JsonSchema; +use arrayvec07::{ArrayString, ArrayVec}; +use std::convert::TryInto; + +// Do not set maxLength on the schema as that describes length in characters, but we only +// know max length in bytes. +forward_impl!(( JsonSchema for ArrayString) => String); + +impl JsonSchema for ArrayVec +where + T: JsonSchema, +{ + no_ref_schema!(); + + fn schema_name() -> String { + format!("Array_up_to_size_{}_of_{}", CAP, T::schema_name()) + } + + fn json_schema(gen: &mut SchemaGenerator) -> Schema { + SchemaObject { + instance_type: Some(InstanceType::Array.into()), + array: Some(Box::new(ArrayValidation { + items: Some(gen.subschema_for::().into()), + max_items: CAP.try_into().ok(), + ..Default::default() + })), + ..Default::default() + } + .into() + } +} diff --git a/schemars/src/json_schema_impls/mod.rs b/schemars/src/json_schema_impls/mod.rs index 950f0f7..9925442 100644 --- a/schemars/src/json_schema_impls/mod.rs +++ b/schemars/src/json_schema_impls/mod.rs @@ -36,8 +36,10 @@ macro_rules! forward_impl { } mod array; -#[cfg(feature = "arrayvec")] -mod arrayvec; +#[cfg(feature = "arrayvec05")] +mod arrayvec05; +#[cfg(feature = "arrayvec07")] +mod arrayvec07; #[cfg(std_atomic)] mod atomic; #[cfg(feature = "bytes")] @@ -45,7 +47,7 @@ mod bytes; #[cfg(feature = "chrono")] mod chrono; mod core; -#[cfg(any(feature = "rust_decimal", feature="bigdecimal"))] +#[cfg(any(feature = "rust_decimal", feature = "bigdecimal"))] mod decimal; #[cfg(feature = "either")] mod either; @@ -66,6 +68,8 @@ mod time; mod tuple; #[cfg(feature = "url")] mod url; -#[cfg(feature = "uuid")] -mod uuid; +#[cfg(feature = "uuid08")] +mod uuid08; +#[cfg(feature = "uuid1")] +mod uuid1; mod wrapper; diff --git a/schemars/src/json_schema_impls/uuid08.rs b/schemars/src/json_schema_impls/uuid08.rs new file mode 100644 index 0000000..9e6dc58 --- /dev/null +++ b/schemars/src/json_schema_impls/uuid08.rs @@ -0,0 +1,21 @@ +use crate::gen::SchemaGenerator; +use crate::schema::*; +use crate::JsonSchema; +use uuid08::Uuid; + +impl JsonSchema for Uuid { + no_ref_schema!(); + + fn schema_name() -> String { + "Uuid".to_string() + } + + fn json_schema(_: &mut SchemaGenerator) -> Schema { + SchemaObject { + instance_type: Some(InstanceType::String.into()), + format: Some("uuid".to_string()), + ..Default::default() + } + .into() + } +} diff --git a/schemars/src/json_schema_impls/uuid.rs b/schemars/src/json_schema_impls/uuid1.rs similarity index 96% rename from schemars/src/json_schema_impls/uuid.rs rename to schemars/src/json_schema_impls/uuid1.rs index c90a78b..85d6789 100644 --- a/schemars/src/json_schema_impls/uuid.rs +++ b/schemars/src/json_schema_impls/uuid1.rs @@ -1,7 +1,7 @@ use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; -use uuid::Uuid; +use uuid1::Uuid; impl JsonSchema for Uuid { no_ref_schema!(); diff --git a/schemars/src/lib.rs b/schemars/src/lib.rs index 5ef0bdf..2094c42 100644 --- a/schemars/src/lib.rs +++ b/schemars/src/lib.rs @@ -259,25 +259,28 @@ println!("{}", serde_json::to_string_pretty(&schema).unwrap()); - `impl_json_schema` - implements `JsonSchema` for Schemars types themselves - `preserve_order` - keep the order of struct fields in `Schema` and `SchemaObject` -## Optional Dependencies -Schemars can implement `JsonSchema` on types from several popular crates, enabled via optional dependencies (dependency versions are shown in brackets): -- [`chrono`](https://crates.io/crates/chrono) (^0.4) -- [`indexmap`](https://crates.io/crates/indexmap) (^1.2) -- [`either`](https://crates.io/crates/either) (^1.3) -- [`uuid`](https://crates.io/crates/uuid) (^0.8) -- [`smallvec`](https://crates.io/crates/smallvec) (^1.0) -- [`arrayvec`](https://crates.io/crates/arrayvec) (^0.5) -- [`url`](https://crates.io/crates/url) (^2.0) -- [`bytes`](https://crates.io/crates/bytes) (^1.0) -- [`enumset`](https://crates.io/crates/enumset) (^1.0) -- [`rust_decimal`](https://crates.io/crates/rust_decimal) (^1.0) -- [`bigdecimal`](https://crates.io/crates/bigdecimal) (^0.3) +Schemars can implement `JsonSchema` on types from several popular crates, enabled via feature flags (dependency versions are shown in brackets): +- `chrono` - [chrono](https://crates.io/crates/chrono) (^0.4) +- `indexmap1` - [indexmap](https://crates.io/crates/indexmap) (^1.2) +- `either` - [either](https://crates.io/crates/either) (^1.3) +- `uuid08` - [uuid](https://crates.io/crates/uuid) (^0.8) +- `uuid1` - [uuid](https://crates.io/crates/uuid) (^1.0) +- `smallvec` - [smallvec](https://crates.io/crates/smallvec) (^1.0) +- `arrayvec05` - [arrayvec](https://crates.io/crates/arrayvec) (^0.5) +- `arrayvec07` - [arrayvec](https://crates.io/crates/arrayvec) (^0.7) +- `url` - [url](https://crates.io/crates/url) (^2.0) +- `bytes` - [bytes](https://crates.io/crates/bytes) (^1.0) +- `enumset` - [enumset](https://crates.io/crates/enumset) (^1.0) +- `rust_decimal` - [rust_decimal](https://crates.io/crates/rust_decimal) (^1.0) +- `bigdecimal` - [bigdecimal](https://crates.io/crates/bigdecimal) (^0.3) For example, to implement `JsonSchema` on types from `chrono`, enable it as a feature in the `schemars` dependency in your `Cargo.toml` like so: ```toml [dependencies] schemars = { version = "0.8", features = ["chrono"] } +``` + ``` */ diff --git a/schemars/tests/arrayvec.rs b/schemars/tests/arrayvec.rs index 62a2676..b00b395 100644 --- a/schemars/tests/arrayvec.rs +++ b/schemars/tests/arrayvec.rs @@ -1,13 +1,22 @@ mod util; -use arrayvec::{ArrayString, ArrayVec}; use util::*; #[test] -fn arrayvec() -> TestResult { - test_default_generated_schema::>("arrayvec") +fn arrayvec05() -> TestResult { + test_default_generated_schema::>("arrayvec") } #[test] -fn arrayvec_string() -> TestResult { - test_default_generated_schema::>("arrayvec_string") +fn arrayvec05_string() -> TestResult { + test_default_generated_schema::>("arrayvec_string") +} + +#[test] +fn arrayvec07() -> TestResult { + test_default_generated_schema::>("arrayvec") +} + +#[test] +fn arrayvec07_string() -> TestResult { + test_default_generated_schema::>("arrayvec_string") } diff --git a/schemars/tests/util/mod.rs b/schemars/tests/util/mod.rs index e83671f..595d68b 100644 --- a/schemars/tests/util/mod.rs +++ b/schemars/tests/util/mod.rs @@ -2,7 +2,6 @@ use pretty_assertions::assert_eq; use schemars::{gen::SchemaSettings, schema::RootSchema, schema_for, JsonSchema}; use std::error::Error; use std::fs; -use std::panic; pub type TestResult = Result<(), Box>; diff --git a/schemars/tests/uuid.rs b/schemars/tests/uuid.rs index 250e2a3..bd673b5 100644 --- a/schemars/tests/uuid.rs +++ b/schemars/tests/uuid.rs @@ -1,8 +1,12 @@ mod util; use util::*; -use uuid::Uuid; #[test] -fn uuid() -> TestResult { - test_default_generated_schema::("uuid") +fn uuid08() -> TestResult { + test_default_generated_schema::("uuid") +} + +#[test] +fn uuid1() -> TestResult { + test_default_generated_schema::("uuid") } diff --git a/schemars_derive/Cargo.toml b/schemars_derive/Cargo.toml index 53a6408..fb058a8 100644 --- a/schemars_derive/Cargo.toml +++ b/schemars_derive/Cargo.toml @@ -17,7 +17,7 @@ proc-macro = true proc-macro2 = "1.0" quote = "1.0" syn = { version = "1.0", features = ["extra-traits"] } -serde_derive_internals = "0.25" +serde_derive_internals = "0.26.0" [dev-dependencies] -pretty_assertions = "0.6.1" +pretty_assertions = "1.2.1"