Skip to content

Commit

Permalink
rebase (#4)
Browse files Browse the repository at this point in the history
* 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 <gesau@hotmail.co.uk>
Co-authored-by: lerencao <funfriendcjf@gmail.com>
Co-authored-by: Graham Esau <graham.esau@vonage.com>
Co-authored-by: Adam Leventhal <adam.leventhal@gmail.com>
Co-authored-by: Matt Campbell <mattcampbell@pobox.com>
Co-authored-by: jolestar <jolestar@gmail.com>
Co-authored-by: timando <github@timando.net>
Co-authored-by: Adam H. Leventhal <ahl@oxide.computer>
  • Loading branch information
9 people authored Jan 2, 2023
1 parent 50cda49 commit 67897a7
Show file tree
Hide file tree
Showing 73 changed files with 2,190 additions and 529 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
test_features: "--features impl_json_schema,chrono,indexmap,either,uuid,smallvec,arrayvec,enumset"
allow_failure: false
- rust: stable
test_features: "--all-features"
Expand All @@ -38,6 +38,8 @@ jobs:
run: cargo check --verbose --no-default-features
continue-on-error: ${{ matrix.allow_failure }}
working-directory: ./schemars
- if: matrix.rust == '1.37.0'
run: cargo update -p indexmap --precise 1.6.2
- name: Run tests
run: cargo test --verbose ${{ matrix.test_features }} --no-fail-fast
continue-on-error: ${{ matrix.allow_failure }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk
.idea
25 changes: 24 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,31 @@
# Changelog

## [0.8.4] - **In-dev**
## [0.8.8] - 2021-11-25
### Added:
- Implement `JsonSchema` for types from `rust_decimal` and `bigdecimal` crates (https://github.com/GREsau/schemars/pull/101)

### Fixed:
- Fixes for internally tagged enums and flattening additional_properties (https://github.com/GREsau/schemars/pull/113)

## [0.8.7] - 2021-11-14
### Added:
- Implement `JsonSchema` for `EnumSet` (https://github.com/GREsau/schemars/pull/92)

### Fixed:
- Do not cause compile error when using a default value that doesn't implement `Serialize` (https://github.com/GREsau/schemars/issues/115)

## [0.8.6] - 2021-09-26
### Changed:
- Use `oneOf` instead of `anyOf` for enums when possible (https://github.com/GREsau/schemars/issues/108)

## [0.8.5] - 2021-09-20
### Fixed:
- Allow fields with plain `#[validate]` attributes (https://github.com/GREsau/schemars/issues/109)

## [0.8.4] - 2021-09-19
### Added:
- `#[schemars(schema_with = "...")]` attribute can now be set on enum variants.
- 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)

## [0.8.3] - 2021-04-05
### Added:
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -274,3 +274,13 @@ Schemars can implement `JsonSchema` on types from several popular crates, enable
- [`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)

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"] }
```
78 changes: 77 additions & 1 deletion docs/1.1-attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ h3 code {

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

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.
[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.

[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.

<details open>
<summary style="font-weight: bold">
Expand All @@ -33,6 +35,13 @@ TABLE OF CONTENTS
- [`skip_deserializing`](#skip_deserializing)
- [`flatten`](#flatten)
- [`with`](#with)
1. [Supported Validator Attributes](#supported-validator-attributes)
- [`email` / `phone` / `url`](#email-phone-url)
- [`length`](#length)
- [`range`](#range)
- [`regex`](#regex)
- [`contains`](#contains)
- [`required` / `required_nested`](#required)
1. [Other Attributes](#other-attributes)
- [`schema_with`](#schema_with)
- [`title` / `description`](#title-description)
Expand Down Expand Up @@ -153,6 +162,73 @@ Serde docs: [container](https://serde.rs/container-attrs.html#transparent)

</div>

## Supported Validator Attributes

<div class="indented">

<h3 id="email-phone-url">

`#[validate(email)]` / `#[schemars(email)]`<br />
`#[validate(phone)]` / `#[schemars(phone)]`<br />
`#[validate(url)]` / `#[schemars(url)]`
</h3>

Sets the schema's `format` to `email`/`phone`/`uri`, as appropriate. Only one of these attributes may be present on a single field.

Validator docs: [email](https://github.com/Keats/validator#email) / [phone](https://github.com/Keats/validator#phone) / [url](https://github.com/Keats/validator#url)

<h3 id="length">

`#[validate(length(min = 1, max = 10))]` / `#[schemars(length(min = 1, max = 10))]`<br />
`#[validate(length(equal = 10))]` / `#[schemars(length(equal = 10))]`
</h3>

Sets the `minLength`/`maxLength` properties for string schemas, or the `minItems`/`maxItems` properties for array schemas.

Validator docs: [length](https://github.com/Keats/validator#length)

<h3 id="range">

`#[validate(range(min = 1, max = 10))]` / `#[schemars(range(min = 1, max = 10))]`
</h3>

Sets the `minimum`/`maximum` properties for number schemas.

Validator docs: [range](https://github.com/Keats/validator#range)

<h3 id="regex">

`#[validate(regex = "path::to::regex")]` / `#[schemars(regex = "path::to::regex")]`
`#[schemars(regex(pattern = r"^\d+$"))]`
</h3>

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.

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.

Validator docs: [regex](https://github.com/Keats/validator#regex)

<h3 id="contains">

`#[validate(contains = "string")]` / `#[schemars(contains = "string")]`
</h3>

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.

Validator docs: [contains](https://github.com/Keats/validator#contains)

<h3 id="required">

`#[validate(required)]` / `#[schemars(required)]`<br />
`#[validate(required_nested)]`
</h3>

When set on an `Option<T>` field, this will create a schemas as though the field were a `T`.

Validator docs: [required](https://github.com/Keats/validator#required) / [required_nested](https://github.com/Keats/validator#required_nested)

</div>

## Other Attributes

<h3 id="schema_with">
Expand Down
3 changes: 3 additions & 0 deletions docs/4-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@ Schemars can implement `JsonSchema` on types from several popular crates, enable
- [`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)
2 changes: 1 addition & 1 deletion docs/_includes/examples/custom_settings.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
},
"definitions": {
"MyEnum": {
"anyOf": [
"oneOf": [
{
"type": "object",
"required": [
Expand Down
2 changes: 1 addition & 1 deletion docs/_includes/examples/doc_comments.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"definitions": {
"MyEnum": {
"title": "My Amazing Enum",
"anyOf": [
"oneOf": [
{
"description": "A wrapper around a `String`",
"type": "object",
Expand Down
2 changes: 1 addition & 1 deletion docs/_includes/examples/main.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
},
"definitions": {
"MyEnum": {
"anyOf": [
"oneOf": [
{
"type": "object",
"required": [
Expand Down
9 changes: 6 additions & 3 deletions docs/_includes/examples/schemars_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
#[schemars(rename_all = "camelCase", deny_unknown_fields)]
pub struct MyStruct {
#[serde(rename = "thisIsOverridden")]
#[schemars(rename = "myNumber")]
#[schemars(rename = "myNumber", range(min = 1, max = 10))]
pub my_int: i32,
pub my_bool: bool,
#[schemars(default)]
Expand All @@ -15,8 +15,11 @@ pub struct MyStruct {
#[derive(Deserialize, Serialize, JsonSchema)]
#[schemars(untagged)]
pub enum MyEnum {
StringNewType(String),
StructVariant { floats: Vec<f32> },
StringNewType(#[schemars(phone)] String),
StructVariant {
#[schemars(length(min = 1, max = 100))]
floats: Vec<f32>,
},
}

fn main() {
Expand Down
11 changes: 8 additions & 3 deletions docs/_includes/examples/schemars_attrs.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@
},
"myNumber": {
"type": "integer",
"format": "int32"
"format": "int32",
"maximum": 10.0,
"minimum": 1.0
}
},
"additionalProperties": false,
"definitions": {
"MyEnum": {
"anyOf": [
{
"type": "string"
"type": "string",
"format": "phone"
},
{
"type": "object",
Expand All @@ -44,7 +47,9 @@
"items": {
"type": "number",
"format": "float"
}
},
"maxItems": 100,
"minItems": 1
}
}
}
Expand Down
24 changes: 24 additions & 0 deletions docs/_includes/examples/validate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use schemars::{schema_for, JsonSchema};

#[derive(JsonSchema)]
pub struct MyStruct {
#[validate(range(min = 1, max = 10))]
pub my_int: i32,
pub my_bool: bool,
#[validate(required)]
pub my_nullable_enum: Option<MyEnum>,
}

#[derive(JsonSchema)]
pub enum MyEnum {
StringNewType(#[validate(phone)] String),
StructVariant {
#[validate(length(min = 1, max = 100))]
floats: Vec<f32>,
},
}

fn main() {
let schema = schema_for!(MyStruct);
println!("{}", serde_json::to_string_pretty(&schema).unwrap());
}
64 changes: 64 additions & 0 deletions docs/_includes/examples/validate.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "MyStruct",
"type": "object",
"required": [
"my_bool",
"my_int",
"my_nullable_enum"
],
"properties": {
"my_bool": {
"type": "boolean"
},
"my_int": {
"type": "integer",
"format": "int32",
"maximum": 10.0,
"minimum": 1.0
},
"my_nullable_enum": {
"oneOf": [
{
"type": "object",
"required": [
"StringNewType"
],
"properties": {
"StringNewType": {
"type": "string",
"format": "phone"
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"StructVariant"
],
"properties": {
"StructVariant": {
"type": "object",
"required": [
"floats"
],
"properties": {
"floats": {
"type": "array",
"items": {
"type": "number",
"format": "float"
},
"maxItems": 100,
"minItems": 1
}
}
}
},
"additionalProperties": false
}
]
}
}
}
2 changes: 1 addition & 1 deletion rust-toolchain
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.51.0
1.57.0
14 changes: 10 additions & 4 deletions schemars/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "schemars"
description = "Generate JSON Schemas from Rust code"
homepage = "https://graham.cool/schemars/"
repository = "https://github.com/GREsau/schemars"
version = "0.8.3"
version = "0.8.8"
authors = ["Graham Esau <gesau@hotmail.co.uk>"]
edition = "2018"
license = "MIT"
Expand All @@ -13,7 +13,7 @@ categories = ["encoding"]
build = "build.rs"

[dependencies]
schemars_derive = { version = "=0.8.3", optional = true, path = "../schemars_derive" }
schemars_derive = { version = "=0.8.8", optional = true, path = "../schemars_derive" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
dyn-clone = "1.0"
Expand All @@ -26,9 +26,11 @@ smallvec = { version = "1.0", optional = true }
arrayvec = { version = "0.5", default-features = false, optional = true }
url = { version = "2.0", default-features = false, optional = true }
bytes = { version = "1.0", optional = true }
move-core-types = { git = "https://github.com/starcoinorg/diem", rev = "69ab01213a2e4128a1a8c8216bbf666c9ef90abd" }
diem-crypto = { package="diem-crypto", git = "https://github.com/starcoinorg/diem", rev="69ab01213a2e4128a1a8c8216bbf666c9ef90abd", features = ["fuzzing"] }
multiaddr = { version = "0.13.0" }
rust_decimal = { version = "1", default-features = false, optional = true }
bigdecimal = { version = "0.3", default-features = false, optional = true }
enumset = { version = "1.0", optional = true }

[dev-dependencies]
pretty_assertions = "0.6.1"
trybuild = "1.0"
Expand Down Expand Up @@ -89,5 +91,9 @@ required-features = ["ui_test"]
name = "url"
required-features = ["url"]

[[test]]
name = "enumset"
required-features = ["enumset"]

[package.metadata.docs.rs]
all-features = true
Loading

0 comments on commit 67897a7

Please sign in to comment.