Skip to content

Commit 67897a7

Browse files
sanlee42GREsaunanne007ahlmwcampbell
authored
rebase (#4)
* Read #[validate(...)] attributes * Handle required flattened Option fields * Refactor out `add_schema_as_property` * Process validation attributes in newtype structs * Process validation attributes in tuple structs * Refactor out "local_id" for type definitions * Refactoring * Support inline regex * Allow setting validation attributes via #[schemars(...)] * Add some doc comments * Fix doc test * Emit compilation errors for duplicate validation attributes * Fix indexmap tests for rust 1.37 * upgrade diem dep (#1) * Update changelog and docs * Add newline to attributes docs * v0.8.4 * Allow empty #[validate] attributes. Fixes GREsau#109 * v0.8.5 * Use oneOf for enums when possible (GREsau#108) * v0.8.6 * Correct latest changelog entry * update diem dep * Implement JsonSchema on EnumSet type * update diem dep * Upgrade move deps (#3) * [deps] Upgrade move types dep. * Update examples after 0a1200b * Allow non-Serialize default values. Default values that don't implement Serialize are now ignored, rather than causing a compile error. This is done by simulating specialization using a technique copied from Rocket: https://github.com/SergioBenitez/Rocket/blob/5ebefa97c992c37bdc476299304a339d429a43fc/core/lib/src/sentinel.rs#L391-L445 Fixes GREsau#115 * v0.8.7 * update diem deps * Add example for optional dependency in readme Based on https://github.com/GREsau/schemars/pull/118/files * Add support for rust_decimal and bigdecimal (GREsau#101) * Document new optional dependencies * Internally tagged enums don't honor deny_unknown_fields as precisely as they might. flatten doesn't act quite as intended with regard to additional_properties * v0.8.8 * update diem deps to latest * update diem deps * Update dep * update diem deps * Update rust toolchain and dep * update diem dep * Update diem dep * [crypto] Update dependency crypto to use starcoinorg/starcoin-crypto repo (#5) * [crypto] Update dependency crypto to use starcoinorg/starcoin-crypto repo. * [deps] Update move-core-types to starcoinorg/move * Remove diem types Co-authored-by: Graham Esau <[email protected]> Co-authored-by: lerencao <[email protected]> Co-authored-by: Graham Esau <[email protected]> Co-authored-by: Adam Leventhal <[email protected]> Co-authored-by: Matt Campbell <[email protected]> Co-authored-by: jolestar <[email protected]> Co-authored-by: timando <[email protected]> Co-authored-by: Adam H. Leventhal <[email protected]>
1 parent 50cda49 commit 67897a7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+2190
-529
lines changed

.github/workflows/ci.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
include:
1616
- rust: 1.37.0
1717
# exclude ui_test as the output is slightly different in rustc 1.37
18-
test_features: "--features impl_json_schema,chrono,indexmap,either,uuid,smallvec,arrayvec"
18+
test_features: "--features impl_json_schema,chrono,indexmap,either,uuid,smallvec,arrayvec,enumset"
1919
allow_failure: false
2020
- rust: stable
2121
test_features: "--all-features"
@@ -38,6 +38,8 @@ jobs:
3838
run: cargo check --verbose --no-default-features
3939
continue-on-error: ${{ matrix.allow_failure }}
4040
working-directory: ./schemars
41+
- if: matrix.rust == '1.37.0'
42+
run: cargo update -p indexmap --precise 1.6.2
4143
- name: Run tests
4244
run: cargo test --verbose ${{ matrix.test_features }} --no-fail-fast
4345
continue-on-error: ${{ matrix.allow_failure }}

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ Cargo.lock
88

99
# These are backup files generated by rustfmt
1010
**/*.rs.bk
11+
.idea

CHANGELOG.md

+24-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,31 @@
11
# Changelog
22

3-
## [0.8.4] - **In-dev**
3+
## [0.8.8] - 2021-11-25
4+
### Added:
5+
- Implement `JsonSchema` for types from `rust_decimal` and `bigdecimal` crates (https://github.com/GREsau/schemars/pull/101)
6+
7+
### Fixed:
8+
- Fixes for internally tagged enums and flattening additional_properties (https://github.com/GREsau/schemars/pull/113)
9+
10+
## [0.8.7] - 2021-11-14
11+
### Added:
12+
- Implement `JsonSchema` for `EnumSet` (https://github.com/GREsau/schemars/pull/92)
13+
14+
### Fixed:
15+
- Do not cause compile error when using a default value that doesn't implement `Serialize` (https://github.com/GREsau/schemars/issues/115)
16+
17+
## [0.8.6] - 2021-09-26
18+
### Changed:
19+
- Use `oneOf` instead of `anyOf` for enums when possible (https://github.com/GREsau/schemars/issues/108)
20+
21+
## [0.8.5] - 2021-09-20
22+
### Fixed:
23+
- Allow fields with plain `#[validate]` attributes (https://github.com/GREsau/schemars/issues/109)
24+
25+
## [0.8.4] - 2021-09-19
426
### Added:
527
- `#[schemars(schema_with = "...")]` attribute can now be set on enum variants.
28+
- Deriving JsonSchema will now take into account `#[validate(...)]` attributes, compatible with the [validator](https://github.com/Keats/validator) crate (https://github.com/GREsau/schemars/pull/78)
629

730
## [0.8.3] - 2021-04-05
831
### Added:

README.md

+10
Original file line numberDiff line numberDiff line change
@@ -274,3 +274,13 @@ Schemars can implement `JsonSchema` on types from several popular crates, enable
274274
- [`arrayvec`](https://crates.io/crates/arrayvec) (^0.5)
275275
- [`url`](https://crates.io/crates/url) (^2.0)
276276
- [`bytes`](https://crates.io/crates/bytes) (^1.0)
277+
- [`enumset`](https://crates.io/crates/enumset) (^1.0)
278+
- [`rust_decimal`](https://crates.io/crates/rust_decimal) (^1.0)
279+
- [`bigdecimal`](https://crates.io/crates/bigdecimal) (^0.3)
280+
281+
For example, to implement `JsonSchema` on types from `chrono`, enable it as a feature in the `schemars` dependency in your `Cargo.toml` like so:
282+
283+
```toml
284+
[dependencies]
285+
schemars = { version = "0.8", features = ["chrono"] }
286+
```

docs/1.1-attributes.md

+77-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ h3 code {
1616

1717
You can add attributes to your types to customize Schemars's derived `JsonSchema` implementation.
1818

19-
Serde also allows setting `#[serde(...)]` attributes which change how types are serialized, and Schemars will generally respect these attributes to ensure that generated schemas will match how the type is serialized by serde_json. `#[serde(...)]` attributes can be overriden using `#[schemars(...)]` attributes, which behave identically (e.g. `#[schemars(rename_all = "camelCase")]`). You may find this useful if you want to change the generated schema without affecting Serde's behaviour, or if you're just not using Serde.
19+
[Serde](https://serde.rs/) allows setting `#[serde(...)]` attributes which change how types are serialized, and Schemars will generally respect these attributes to ensure that generated schemas will match how the type is serialized by serde_json. `#[serde(...)]` attributes can be overriden using `#[schemars(...)]` attributes, which behave identically (e.g. `#[schemars(rename_all = "camelCase")]`). You may find this useful if you want to change the generated schema without affecting Serde's behaviour, or if you're just not using Serde.
20+
21+
[Validator](https://github.com/Keats/validator) allows setting `#[validate(...)]` attributes to restrict valid values of particular fields, many of which will be used by Schemars to generate more accurate schemas. These can also be overridden by `#[schemars(...)]` attributes.
2022

2123
<details open>
2224
<summary style="font-weight: bold">
@@ -33,6 +35,13 @@ TABLE OF CONTENTS
3335
- [`skip_deserializing`](#skip_deserializing)
3436
- [`flatten`](#flatten)
3537
- [`with`](#with)
38+
1. [Supported Validator Attributes](#supported-validator-attributes)
39+
- [`email` / `phone` / `url`](#email-phone-url)
40+
- [`length`](#length)
41+
- [`range`](#range)
42+
- [`regex`](#regex)
43+
- [`contains`](#contains)
44+
- [`required` / `required_nested`](#required)
3645
1. [Other Attributes](#other-attributes)
3746
- [`schema_with`](#schema_with)
3847
- [`title` / `description`](#title-description)
@@ -153,6 +162,73 @@ Serde docs: [container](https://serde.rs/container-attrs.html#transparent)
153162

154163
</div>
155164

165+
## Supported Validator Attributes
166+
167+
<div class="indented">
168+
169+
<h3 id="email-phone-url">
170+
171+
`#[validate(email)]` / `#[schemars(email)]`<br />
172+
`#[validate(phone)]` / `#[schemars(phone)]`<br />
173+
`#[validate(url)]` / `#[schemars(url)]`
174+
</h3>
175+
176+
Sets the schema's `format` to `email`/`phone`/`uri`, as appropriate. Only one of these attributes may be present on a single field.
177+
178+
Validator docs: [email](https://github.com/Keats/validator#email) / [phone](https://github.com/Keats/validator#phone) / [url](https://github.com/Keats/validator#url)
179+
180+
<h3 id="length">
181+
182+
`#[validate(length(min = 1, max = 10))]` / `#[schemars(length(min = 1, max = 10))]`<br />
183+
`#[validate(length(equal = 10))]` / `#[schemars(length(equal = 10))]`
184+
</h3>
185+
186+
Sets the `minLength`/`maxLength` properties for string schemas, or the `minItems`/`maxItems` properties for array schemas.
187+
188+
Validator docs: [length](https://github.com/Keats/validator#length)
189+
190+
<h3 id="range">
191+
192+
`#[validate(range(min = 1, max = 10))]` / `#[schemars(range(min = 1, max = 10))]`
193+
</h3>
194+
195+
Sets the `minimum`/`maximum` properties for number schemas.
196+
197+
Validator docs: [range](https://github.com/Keats/validator#range)
198+
199+
<h3 id="regex">
200+
201+
`#[validate(regex = "path::to::regex")]` / `#[schemars(regex = "path::to::regex")]`
202+
`#[schemars(regex(pattern = r"^\d+$"))]`
203+
</h3>
204+
205+
Sets the `pattern` property for string schemas. The `path::to::regex` will typically refer to a [`Regex`](https://docs.rs/regex/*/regex/struct.Regex.html) instance, but Schemars allows it to be any value with a `to_string()` method.
206+
207+
Providing an inline regex pattern using `regex(pattern = ...)` is a Schemars extension, and not currently supported by the Validator crate. When using this form, you may want to use a `r"raw string literal"` so that `\\` characters in the regex pattern are not interpreted as escape sequences in the string.
208+
209+
Validator docs: [regex](https://github.com/Keats/validator#regex)
210+
211+
<h3 id="contains">
212+
213+
`#[validate(contains = "string")]` / `#[schemars(contains = "string")]`
214+
</h3>
215+
216+
For string schemas, sets the `pattern` property to the given value, with any regex special characters escaped. For object schemas (e.g. when the attribute is set on a HashMap field), includes the value in the `required` property, indicating that the map must contain it as a key.
217+
218+
Validator docs: [contains](https://github.com/Keats/validator#contains)
219+
220+
<h3 id="required">
221+
222+
`#[validate(required)]` / `#[schemars(required)]`<br />
223+
`#[validate(required_nested)]`
224+
</h3>
225+
226+
When set on an `Option<T>` field, this will create a schemas as though the field were a `T`.
227+
228+
Validator docs: [required](https://github.com/Keats/validator#required) / [required_nested](https://github.com/Keats/validator#required_nested)
229+
230+
</div>
231+
156232
## Other Attributes
157233

158234
<h3 id="schema_with">

docs/4-features.md

+3
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,6 @@ Schemars can implement `JsonSchema` on types from several popular crates, enable
2828
- [`arrayvec`](https://crates.io/crates/arrayvec) (^0.5)
2929
- [`url`](https://crates.io/crates/url) (^2.0)
3030
- [`bytes`](https://crates.io/crates/bytes) (^1.0)
31+
- [`enumset`](https://crates.io/crates/enumset) (^1.0)
32+
- [`rust_decimal`](https://crates.io/crates/rust_decimal) (^1.0)
33+
- [`bigdecimal`](https://crates.io/crates/bigdecimal) (^0.3)

docs/_includes/examples/custom_settings.schema.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
},
2626
"definitions": {
2727
"MyEnum": {
28-
"anyOf": [
28+
"oneOf": [
2929
{
3030
"type": "object",
3131
"required": [

docs/_includes/examples/doc_comments.schema.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"definitions": {
3434
"MyEnum": {
3535
"title": "My Amazing Enum",
36-
"anyOf": [
36+
"oneOf": [
3737
{
3838
"description": "A wrapper around a `String`",
3939
"type": "object",

docs/_includes/examples/main.schema.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
},
2828
"definitions": {
2929
"MyEnum": {
30-
"anyOf": [
30+
"oneOf": [
3131
{
3232
"type": "object",
3333
"required": [

docs/_includes/examples/schemars_attrs.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
55
#[schemars(rename_all = "camelCase", deny_unknown_fields)]
66
pub struct MyStruct {
77
#[serde(rename = "thisIsOverridden")]
8-
#[schemars(rename = "myNumber")]
8+
#[schemars(rename = "myNumber", range(min = 1, max = 10))]
99
pub my_int: i32,
1010
pub my_bool: bool,
1111
#[schemars(default)]
@@ -15,8 +15,11 @@ pub struct MyStruct {
1515
#[derive(Deserialize, Serialize, JsonSchema)]
1616
#[schemars(untagged)]
1717
pub enum MyEnum {
18-
StringNewType(String),
19-
StructVariant { floats: Vec<f32> },
18+
StringNewType(#[schemars(phone)] String),
19+
StructVariant {
20+
#[schemars(length(min = 1, max = 100))]
21+
floats: Vec<f32>,
22+
},
2023
}
2124

2225
fn main() {

docs/_includes/examples/schemars_attrs.schema.json

+8-3
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,18 @@
2323
},
2424
"myNumber": {
2525
"type": "integer",
26-
"format": "int32"
26+
"format": "int32",
27+
"maximum": 10.0,
28+
"minimum": 1.0
2729
}
2830
},
2931
"additionalProperties": false,
3032
"definitions": {
3133
"MyEnum": {
3234
"anyOf": [
3335
{
34-
"type": "string"
36+
"type": "string",
37+
"format": "phone"
3538
},
3639
{
3740
"type": "object",
@@ -44,7 +47,9 @@
4447
"items": {
4548
"type": "number",
4649
"format": "float"
47-
}
50+
},
51+
"maxItems": 100,
52+
"minItems": 1
4853
}
4954
}
5055
}

docs/_includes/examples/validate.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use schemars::{schema_for, JsonSchema};
2+
3+
#[derive(JsonSchema)]
4+
pub struct MyStruct {
5+
#[validate(range(min = 1, max = 10))]
6+
pub my_int: i32,
7+
pub my_bool: bool,
8+
#[validate(required)]
9+
pub my_nullable_enum: Option<MyEnum>,
10+
}
11+
12+
#[derive(JsonSchema)]
13+
pub enum MyEnum {
14+
StringNewType(#[validate(phone)] String),
15+
StructVariant {
16+
#[validate(length(min = 1, max = 100))]
17+
floats: Vec<f32>,
18+
},
19+
}
20+
21+
fn main() {
22+
let schema = schema_for!(MyStruct);
23+
println!("{}", serde_json::to_string_pretty(&schema).unwrap());
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"title": "MyStruct",
4+
"type": "object",
5+
"required": [
6+
"my_bool",
7+
"my_int",
8+
"my_nullable_enum"
9+
],
10+
"properties": {
11+
"my_bool": {
12+
"type": "boolean"
13+
},
14+
"my_int": {
15+
"type": "integer",
16+
"format": "int32",
17+
"maximum": 10.0,
18+
"minimum": 1.0
19+
},
20+
"my_nullable_enum": {
21+
"oneOf": [
22+
{
23+
"type": "object",
24+
"required": [
25+
"StringNewType"
26+
],
27+
"properties": {
28+
"StringNewType": {
29+
"type": "string",
30+
"format": "phone"
31+
}
32+
},
33+
"additionalProperties": false
34+
},
35+
{
36+
"type": "object",
37+
"required": [
38+
"StructVariant"
39+
],
40+
"properties": {
41+
"StructVariant": {
42+
"type": "object",
43+
"required": [
44+
"floats"
45+
],
46+
"properties": {
47+
"floats": {
48+
"type": "array",
49+
"items": {
50+
"type": "number",
51+
"format": "float"
52+
},
53+
"maxItems": 100,
54+
"minItems": 1
55+
}
56+
}
57+
}
58+
},
59+
"additionalProperties": false
60+
}
61+
]
62+
}
63+
}
64+
}

rust-toolchain

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.51.0
1+
1.57.0

schemars/Cargo.toml

+10-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "schemars"
33
description = "Generate JSON Schemas from Rust code"
44
homepage = "https://graham.cool/schemars/"
55
repository = "https://github.com/GREsau/schemars"
6-
version = "0.8.3"
6+
version = "0.8.8"
77
authors = ["Graham Esau <[email protected]>"]
88
edition = "2018"
99
license = "MIT"
@@ -13,7 +13,7 @@ categories = ["encoding"]
1313
build = "build.rs"
1414

1515
[dependencies]
16-
schemars_derive = { version = "=0.8.3", optional = true, path = "../schemars_derive" }
16+
schemars_derive = { version = "=0.8.8", optional = true, path = "../schemars_derive" }
1717
serde = { version = "1.0", features = ["derive"] }
1818
serde_json = "1.0"
1919
dyn-clone = "1.0"
@@ -26,9 +26,11 @@ smallvec = { version = "1.0", optional = true }
2626
arrayvec = { version = "0.5", default-features = false, optional = true }
2727
url = { version = "2.0", default-features = false, optional = true }
2828
bytes = { version = "1.0", optional = true }
29-
move-core-types = { git = "https://github.com/starcoinorg/diem", rev = "69ab01213a2e4128a1a8c8216bbf666c9ef90abd" }
30-
diem-crypto = { package="diem-crypto", git = "https://github.com/starcoinorg/diem", rev="69ab01213a2e4128a1a8c8216bbf666c9ef90abd", features = ["fuzzing"] }
3129
multiaddr = { version = "0.13.0" }
30+
rust_decimal = { version = "1", default-features = false, optional = true }
31+
bigdecimal = { version = "0.3", default-features = false, optional = true }
32+
enumset = { version = "1.0", optional = true }
33+
3234
[dev-dependencies]
3335
pretty_assertions = "0.6.1"
3436
trybuild = "1.0"
@@ -89,5 +91,9 @@ required-features = ["ui_test"]
8991
name = "url"
9092
required-features = ["url"]
9193

94+
[[test]]
95+
name = "enumset"
96+
required-features = ["enumset"]
97+
9298
[package.metadata.docs.rs]
9399
all-features = true

0 commit comments

Comments
 (0)