schemars-0.8.16/.cargo_vcs_info.json0000644000000001460000000000100127360ustar { "git": { "sha1": "e04e3a3a8191bac1f218539733110fcc26bdbf7c" }, "path_in_vcs": "schemars" }schemars-0.8.16/.gitignore000064400000000000000000000001140072674642500135410ustar 00000000000000/target **/*.rs.bk Cargo.lock /tests/actual/*.json /tests/expected/README.mdschemars-0.8.16/Cargo.lock0000644000000345070000000000100107210ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "arrayvec" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "arrayvec" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "basic-toml" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7bfc506e7a2370ec239e1d072507b2a80c833083699d3c6fa176fbb4de8448c6" dependencies = [ "serde", ] [[package]] name = "bigdecimal" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" dependencies = [ "num-bigint", "num-integer", "num-traits", ] [[package]] name = "bigdecimal" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06619be423ea5bb86c95f087d5707942791a08a85530df0db2209a3ecfb8bc9" dependencies = [ "autocfg", "libm", "num-bigint", "num-integer", "num-traits", ] [[package]] name = "bytes" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "chrono" version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "num-traits", ] [[package]] name = "darling" version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ "darling_core", "darling_macro", ] [[package]] name = "darling_core" version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "syn 2.0.38", ] [[package]] name = "darling_macro" version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", "syn 2.0.38", ] [[package]] name = "diff" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" [[package]] name = "dyn-clone" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" [[package]] name = "either" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "enumset" version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" dependencies = [ "darling", "proc-macro2", "quote", "syn 2.0.38", ] [[package]] name = "equivalent" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] [[package]] name = "glob" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "ident_case" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ "unicode-bidi", "unicode-normalization", ] [[package]] name = "indexmap" version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", "serde", ] [[package]] name = "indexmap" version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" dependencies = [ "equivalent", "hashbrown 0.14.2", "serde", ] [[package]] name = "itoa" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "libm" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "num-bigint" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", "num-traits", ] [[package]] name = "num-integer" version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ "autocfg", "num-traits", ] [[package]] name = "num-traits" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] [[package]] name = "once_cell" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "percent-encoding" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pretty_assertions" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" dependencies = [ "diff", "yansi", ] [[package]] name = "proc-macro2" version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] [[package]] name = "rust_decimal" version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4c4216490d5a413bc6d10fa4742bd7d4955941d062c0ef873141d6b0e7b30fd" dependencies = [ "arrayvec 0.7.4", "num-traits", ] [[package]] name = "ryu" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "schemars" version = "0.8.16" dependencies = [ "arrayvec 0.5.2", "arrayvec 0.7.4", "bigdecimal 0.3.1", "bigdecimal 0.4.2", "bytes", "chrono", "dyn-clone", "either", "enumset", "indexmap 1.9.3", "indexmap 2.0.2", "pretty_assertions", "rust_decimal", "schemars_derive", "semver", "serde", "serde_json", "smallvec", "smol_str", "trybuild", "url", "uuid 0.8.2", "uuid 1.5.0", ] [[package]] name = "schemars_derive" version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", "syn 1.0.109", ] [[package]] name = "semver" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" dependencies = [ "serde", ] [[package]] name = "serde" version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", "syn 2.0.38", ] [[package]] name = "serde_derive_internals" version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ "proc-macro2", "quote", "syn 1.0.109", ] [[package]] name = "serde_json" version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", "serde", ] [[package]] name = "smallvec" version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "smol_str" version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fad6c857cbab2627dcf01ec85a623ca4e7dcb5691cbaa3d7fb7653671f0d09c9" dependencies = [ "serde", ] [[package]] name = "syn" version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "syn" version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "termcolor" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" dependencies = [ "winapi-util", ] [[package]] name = "tinyvec" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ "tinyvec_macros", ] [[package]] name = "tinyvec_macros" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "trybuild" version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "196a58260a906cedb9bf6d8034b6379d0c11f552416960452f267402ceeddff1" dependencies = [ "basic-toml", "glob", "once_cell", "serde", "serde_derive", "serde_json", "termcolor", ] [[package]] name = "unicode-bidi" version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] [[package]] name = "url" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] [[package]] name = "uuid" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "uuid" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "yansi" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" schemars-0.8.16/Cargo.toml0000644000000076150000000000100107440ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" rust-version = "1.60" name = "schemars" version = "0.8.16" authors = ["Graham Esau "] build = "build.rs" description = "Generate JSON Schemas from Rust code" homepage = "https://graham.cool/schemars/" readme = "README.md" keywords = [ "rust", "json-schema", "serde", ] categories = ["encoding"] license = "MIT" repository = "https://github.com/GREsau/schemars" [package.metadata.docs.rs] all-features = true [[test]] name = "chrono" required-features = ["chrono"] [[test]] name = "indexmap" required-features = ["indexmap"] [[test]] name = "indexmap2" required-features = ["indexmap2"] [[test]] name = "either" required-features = ["either"] [[test]] name = "uuid" required-features = [ "uuid08", "uuid1", ] [[test]] name = "smallvec" required-features = ["smallvec"] [[test]] name = "bytes" required-features = ["bytes"] [[test]] name = "arrayvec" required-features = [ "arrayvec05", "arrayvec07", ] [[test]] name = "schema_for_schema" required-features = ["impl_json_schema"] [[test]] name = "ui" required-features = ["ui_test"] [[test]] name = "url" required-features = ["url"] [[test]] name = "enumset" required-features = ["enumset"] [[test]] name = "smol_str" required-features = ["smol_str"] [[test]] name = "semver" required-features = ["semver"] [[test]] name = "decimal" required-features = [ "rust_decimal", "bigdecimal03", "bigdecimal04", ] [dependencies.arrayvec05] version = "0.5" optional = true default-features = false package = "arrayvec" [dependencies.arrayvec07] version = "0.7" optional = true default-features = false package = "arrayvec" [dependencies.bigdecimal03] version = "0.3" optional = true default-features = false package = "bigdecimal" [dependencies.bigdecimal04] version = "0.4" optional = true default-features = false package = "bigdecimal" [dependencies.bytes] version = "1.0" optional = true [dependencies.chrono] version = "0.4" optional = true default-features = false [dependencies.dyn-clone] version = "1.0" [dependencies.either] version = "1.3" optional = true default-features = false [dependencies.enumset] version = "1.0" optional = true [dependencies.indexmap] version = "1.2" features = ["serde-1"] optional = true [dependencies.indexmap2] version = "2.0" features = ["serde"] optional = true package = "indexmap" [dependencies.rust_decimal] version = "1" optional = true default-features = false [dependencies.schemars_derive] version = "=0.8.16" optional = true [dependencies.semver] version = "1.0.9" features = ["serde"] optional = true [dependencies.serde] version = "1.0" features = ["derive"] [dependencies.serde_json] version = "1.0.25" [dependencies.smallvec] version = "1.0" optional = true [dependencies.smol_str] version = "0.1.17" optional = true [dependencies.url] version = "2.0" optional = true default-features = false [dependencies.uuid08] version = "0.8" optional = true default-features = false package = "uuid" [dependencies.uuid1] version = "1.0" optional = true default-features = false package = "uuid" [dev-dependencies.pretty_assertions] version = "1.2.1" [dev-dependencies.trybuild] version = "1.0" [features] arrayvec = ["arrayvec05"] bigdecimal = ["bigdecimal03"] default = ["derive"] derive = ["schemars_derive"] derive_json_schema = ["impl_json_schema"] impl_json_schema = ["derive"] indexmap1 = ["indexmap"] preserve_order = ["indexmap"] raw_value = ["serde_json/raw_value"] ui_test = [] uuid = ["uuid08"] schemars-0.8.16/Cargo.toml.orig000064400000000000000000000074510072674642500144530ustar 00000000000000[package] name = "schemars" description = "Generate JSON Schemas from Rust code" homepage = "https://graham.cool/schemars/" repository = "https://github.com/GREsau/schemars" version = "0.8.16" authors = ["Graham Esau "] edition = "2021" license = "MIT" readme = "README.md" keywords = ["rust", "json-schema", "serde"] categories = ["encoding"] build = "build.rs" rust-version = "1.60" [dependencies] schemars_derive = { version = "=0.8.16", optional = true, path = "../schemars_derive" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.25" dyn-clone = "1.0" chrono = { version = "0.4", default-features = false, optional = true } indexmap = { version = "1.2", features = ["serde-1"], optional = true } indexmap2 = { version = "2.0", features = ["serde"], optional = true, package = "indexmap" } either = { version = "1.3", 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 } 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 } bigdecimal03 = { version = "0.3", default-features = false, optional = true, package = "bigdecimal" } bigdecimal04 = { version = "0.4", default-features = false, optional = true, package = "bigdecimal" } enumset = { version = "1.0", optional = true } smol_str = { version = "0.1.17", optional = true } semver = { version = "1.0.9", features = ["serde"], optional = true } [dev-dependencies] pretty_assertions = "1.2.1" trybuild = "1.0" [features] default = ["derive"] derive = ["schemars_derive"] # Use a different representation for the map type of Schemars. # This allows data to be read into a Value and written back to a JSON string # while preserving the order of map keys in the input. preserve_order = ["indexmap"] 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"] raw_value = ["serde_json/raw_value"] # `bigdecimal` feature without version suffix is included only for back-compat - will be removed in a later version bigdecimal = ["bigdecimal03"] ui_test = [] [[test]] name = "chrono" required-features = ["chrono"] [[test]] name = "indexmap" required-features = ["indexmap"] [[test]] name = "indexmap2" required-features = ["indexmap2"] [[test]] name = "either" required-features = ["either"] [[test]] name = "uuid" required-features = ["uuid08", "uuid1"] [[test]] name = "smallvec" required-features = ["smallvec"] [[test]] name = "bytes" required-features = ["bytes"] [[test]] name = "arrayvec" required-features = ["arrayvec05", "arrayvec07"] [[test]] name = "schema_for_schema" required-features = ["impl_json_schema"] [[test]] name = "ui" required-features = ["ui_test"] [[test]] name = "url" required-features = ["url"] [[test]] name = "enumset" required-features = ["enumset"] [[test]] name = "smol_str" required-features = ["smol_str"] [[test]] name = "semver" required-features = ["semver"] [[test]] name = "decimal" required-features = ["rust_decimal", "bigdecimal03", "bigdecimal04"] [package.metadata.docs.rs] all-features = true schemars-0.8.16/LICENSE000064400000000000000000000020540072674642500125630ustar 00000000000000MIT License Copyright (c) 2019 Graham Esau Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. schemars-0.8.16/README.md000064400000000000000000000201200072674642500130270ustar 00000000000000# Schemars [![CI Build](https://img.shields.io/github/actions/workflow/status/GREsau/schemars/ci.yml?branch=master&logo=GitHub)](https://github.com/GREsau/schemars/actions) [![Crates.io](https://img.shields.io/crates/v/schemars)](https://crates.io/crates/schemars) [![Docs](https://docs.rs/schemars/badge.svg)](https://docs.rs/schemars) [![MSRV 1.60+](https://img.shields.io/badge/schemars-rustc_1.60+-lightgray.svg)](https://blog.rust-lang.org/2022/04/07/Rust-1.60.0.html) Generate JSON Schema documents from Rust code ## Basic Usage If you don't really care about the specifics, the easiest way to generate a JSON schema for your types is to `#[derive(JsonSchema)]` and use the `schema_for!` macro. All fields of the type must also implement `JsonSchema` - Schemars implements this for many standard library types. ```rust use schemars::{schema_for, JsonSchema}; #[derive(JsonSchema)] pub struct MyStruct { pub my_int: i32, pub my_bool: bool, pub my_nullable_enum: Option, } #[derive(JsonSchema)] pub enum MyEnum { StringNewType(String), StructVariant { floats: Vec }, } let schema = schema_for!(MyStruct); println!("{}", serde_json::to_string_pretty(&schema).unwrap()); ```
Click to see the output JSON schema... ```json { "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyStruct", "type": "object", "required": ["my_bool", "my_int"], "properties": { "my_bool": { "type": "boolean" }, "my_int": { "type": "integer", "format": "int32" }, "my_nullable_enum": { "anyOf": [ { "$ref": "#/definitions/MyEnum" }, { "type": "null" } ] } }, "definitions": { "MyEnum": { "anyOf": [ { "type": "object", "required": ["StringNewType"], "properties": { "StringNewType": { "type": "string" } }, "additionalProperties": false }, { "type": "object", "required": ["StructVariant"], "properties": { "StructVariant": { "type": "object", "required": ["floats"], "properties": { "floats": { "type": "array", "items": { "type": "number", "format": "float" } } } } }, "additionalProperties": false } ] } } } ```
### Serde Compatibility One of the main aims of this library is compatibility with [Serde](https://github.com/serde-rs/serde). Any generated schema _should_ match how [serde_json](https://github.com/serde-rs/json) would serialize/deserialize to/from JSON. To support this, Schemars will check for any `#[serde(...)]` attributes on types that derive `JsonSchema`, and adjust the generated schema accordingly. ```rust use schemars::{schema_for, JsonSchema}; use serde::{Deserialize, Serialize}; #[derive(Deserialize, Serialize, JsonSchema)] #[serde(rename_all = "camelCase", deny_unknown_fields)] pub struct MyStruct { #[serde(rename = "myNumber")] pub my_int: i32, pub my_bool: bool, #[serde(default)] pub my_nullable_enum: Option, } #[derive(Deserialize, Serialize, JsonSchema)] #[serde(untagged)] pub enum MyEnum { StringNewType(String), StructVariant { floats: Vec }, } let schema = schema_for!(MyStruct); println!("{}", serde_json::to_string_pretty(&schema).unwrap()); ```
Click to see the output JSON schema... ```json { "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyStruct", "type": "object", "required": ["myBool", "myNumber"], "properties": { "myBool": { "type": "boolean" }, "myNullableEnum": { "default": null, "anyOf": [ { "$ref": "#/definitions/MyEnum" }, { "type": "null" } ] }, "myNumber": { "type": "integer", "format": "int32" } }, "additionalProperties": false, "definitions": { "MyEnum": { "anyOf": [ { "type": "string" }, { "type": "object", "required": ["floats"], "properties": { "floats": { "type": "array", "items": { "type": "number", "format": "float" } } } } ] } } } ```
`#[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. ### Schema from Example Value If you want a schema for a type that can't/doesn't implement `JsonSchema`, but does implement `serde::Serialize`, then you can generate a JSON schema from a value of that type. However, this schema will generally be less precise than if the type implemented `JsonSchema` - particularly when it involves enums, since schemars will not make any assumptions about the structure of an enum based on a single variant. ```rust use schemars::schema_for_value; use serde::Serialize; #[derive(Serialize)] pub struct MyStruct { pub my_int: i32, pub my_bool: bool, pub my_nullable_enum: Option, } #[derive(Serialize)] pub enum MyEnum { StringNewType(String), StructVariant { floats: Vec }, } let schema = schema_for_value!(MyStruct { my_int: 123, my_bool: true, my_nullable_enum: Some(MyEnum::StringNewType("foo".to_string())) }); println!("{}", serde_json::to_string_pretty(&schema).unwrap()); ```
Click to see the output JSON schema... ```json { "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyStruct", "examples": [ { "my_bool": true, "my_int": 123, "my_nullable_enum": { "StringNewType": "foo" } } ], "type": "object", "properties": { "my_bool": { "type": "boolean" }, "my_int": { "type": "integer" }, "my_nullable_enum": true } } ```
## 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` - `raw_value` - implements `JsonSchema` for `serde_json::value::RawValue` (enables the serde_json `raw_value` feature) 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) - `indexmap2` - [indexmap](https://crates.io/crates/indexmap) (^2.0) - `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) - `bigdecimal03` - [bigdecimal](https://crates.io/crates/bigdecimal) (^0.3) - `bigdecimal04` - [bigdecimal](https://crates.io/crates/bigdecimal) (^0.4) - `smol_str` - [smol_str](https://crates.io/crates/smol_str) (^0.1.17) - `semver` - [semver](https://crates.io/crates/semver) (^1.0.9) 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"] } ``` schemars-0.8.16/build.rs000064400000000000000000000016510072674642500132250ustar 00000000000000use std::env; // Based on https://github.com/serde-rs/serde/blob/master/serde/build.rs fn main() { let target = env::var("TARGET").unwrap(); let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten"; // Whitelist of archs that support std::sync::atomic module. Ideally we // would use #[cfg(target_has_atomic = "...")] but it is not stable yet. // Instead this is based on rustc's src/librustc_target/spec/*.rs. let has_atomic64 = target.starts_with("x86_64") || target.starts_with("i686") || target.starts_with("aarch64") || target.starts_with("powerpc64") || target.starts_with("sparc64") || target.starts_with("mips64el"); let has_atomic32 = has_atomic64 || emscripten; if has_atomic64 { println!("cargo:rustc-cfg=std_atomic64"); } if has_atomic32 { println!("cargo:rustc-cfg=std_atomic"); } } schemars-0.8.16/examples/custom_serialization.rs000064400000000000000000000031400072674642500202060ustar 00000000000000use schemars::schema::{Schema, SchemaObject}; use schemars::{gen::SchemaGenerator, schema_for, JsonSchema}; use serde::{Deserialize, Serialize}; // `int_as_string` and `bool_as_string` use the schema for `String`. #[derive(Default, Deserialize, Serialize, JsonSchema)] pub struct MyStruct { #[serde(default = "eight", with = "as_string")] #[schemars(with = "String")] pub int_as_string: i32, #[serde(default = "eight")] pub int_normal: i32, #[serde(default, with = "as_string")] #[schemars(schema_with = "make_custom_schema")] pub bool_as_string: bool, #[serde(default)] pub bool_normal: bool, } fn make_custom_schema(gen: &mut SchemaGenerator) -> Schema { let mut schema: SchemaObject = ::json_schema(gen).into(); schema.format = Some("boolean".to_owned()); schema.into() } fn eight() -> i32 { 8 } // This module serializes values as strings mod as_string { use serde::{de::Error, Deserialize, Deserializer, Serializer}; pub fn serialize(value: &T, serializer: S) -> Result where T: std::fmt::Display, S: Serializer, { serializer.collect_str(value) } pub fn deserialize<'de, T, D>(deserializer: D) -> Result where T: std::str::FromStr, D: Deserializer<'de>, { let string = String::deserialize(deserializer)?; string .parse() .map_err(|_| D::Error::custom("Input was not valid")) } } fn main() { let schema = schema_for!(MyStruct); println!("{}", serde_json::to_string_pretty(&schema).unwrap()); } schemars-0.8.16/examples/custom_serialization.schema.json000064400000000000000000000007360072674642500220020ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyStruct", "type": "object", "properties": { "bool_as_string": { "default": "false", "type": "string", "format": "boolean" }, "bool_normal": { "default": false, "type": "boolean" }, "int_as_string": { "default": "8", "type": "string" }, "int_normal": { "default": 8, "type": "integer", "format": "int32" } } } schemars-0.8.16/examples/custom_settings.rs000064400000000000000000000011430072674642500171720ustar 00000000000000use schemars::{gen::SchemaSettings, JsonSchema}; #[derive(JsonSchema)] pub struct MyStruct { pub my_int: i32, pub my_bool: bool, pub my_nullable_enum: Option, } #[derive(JsonSchema)] pub enum MyEnum { StringNewType(String), StructVariant { floats: Vec }, } fn main() { let settings = SchemaSettings::draft07().with(|s| { s.option_nullable = true; s.option_add_null_type = false; }); let gen = settings.into_generator(); let schema = gen.into_root_schema_for::(); println!("{}", serde_json::to_string_pretty(&schema).unwrap()); } schemars-0.8.16/examples/custom_settings.schema.json000064400000000000000000000025270072674642500207650ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyStruct", "type": "object", "required": [ "my_bool", "my_int" ], "properties": { "my_bool": { "type": "boolean" }, "my_int": { "type": "integer", "format": "int32" }, "my_nullable_enum": { "allOf": [ { "$ref": "#/definitions/MyEnum" } ], "nullable": true } }, "definitions": { "MyEnum": { "oneOf": [ { "type": "object", "required": [ "StringNewType" ], "properties": { "StringNewType": { "type": "string" } }, "additionalProperties": false }, { "type": "object", "required": [ "StructVariant" ], "properties": { "StructVariant": { "type": "object", "required": [ "floats" ], "properties": { "floats": { "type": "array", "items": { "type": "number", "format": "float" } } } } }, "additionalProperties": false } ] } } } schemars-0.8.16/examples/doc_comments.rs000064400000000000000000000015170072674642500164170ustar 00000000000000use schemars::{schema_for, JsonSchema}; /// # My Amazing Struct /// This struct shows off generating a schema with /// a custom title and description. #[derive(JsonSchema)] pub struct MyStruct { /// # My Amazing Integer pub my_int: i32, /// This bool has a description, but no title. pub my_bool: bool, /// # A Nullable Enum /// This enum might be set, or it might not. pub my_nullable_enum: Option, } /// # My Amazing Enum #[derive(JsonSchema)] pub enum MyEnum { /// A wrapper around a `String` StringNewType(String), /// A struct-like enum variant which contains /// some floats StructVariant { /// The floats themselves floats: Vec, }, } fn main() { let schema = schema_for!(MyStruct); println!("{}", serde_json::to_string_pretty(&schema).unwrap()); } schemars-0.8.16/examples/doc_comments.schema.json000064400000000000000000000036120072674642500202010ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "My Amazing Struct", "description": "This struct shows off generating a schema with a custom title and description.", "type": "object", "required": [ "my_bool", "my_int" ], "properties": { "my_bool": { "description": "This bool has a description, but no title.", "type": "boolean" }, "my_int": { "title": "My Amazing Integer", "type": "integer", "format": "int32" }, "my_nullable_enum": { "title": "A Nullable Enum", "description": "This enum might be set, or it might not.", "anyOf": [ { "$ref": "#/definitions/MyEnum" }, { "type": "null" } ] } }, "definitions": { "MyEnum": { "title": "My Amazing Enum", "oneOf": [ { "description": "A wrapper around a `String`", "type": "object", "required": [ "StringNewType" ], "properties": { "StringNewType": { "type": "string" } }, "additionalProperties": false }, { "description": "A struct-like enum variant which contains some floats", "type": "object", "required": [ "StructVariant" ], "properties": { "StructVariant": { "type": "object", "required": [ "floats" ], "properties": { "floats": { "description": "The floats themselves", "type": "array", "items": { "type": "number", "format": "float" } } } } }, "additionalProperties": false } ] } } } schemars-0.8.16/examples/enum_repr.rs000064400000000000000000000004370072674642500157410ustar 00000000000000use schemars::{schema_for, JsonSchema_repr}; #[derive(JsonSchema_repr)] #[repr(u8)] enum SmallPrime { Two = 2, Three = 3, Five = 5, Seven = 7, } fn main() { let schema = schema_for!(SmallPrime); println!("{}", serde_json::to_string_pretty(&schema).unwrap()); } schemars-0.8.16/examples/enum_repr.schema.json000064400000000000000000000002250072674642500175200ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "SmallPrime", "type": "integer", "enum": [ 2, 3, 5, 7 ] } schemars-0.8.16/examples/from_value.rs000064400000000000000000000010450072674642500161000ustar 00000000000000use schemars::schema_for_value; use serde::Serialize; #[derive(Serialize)] pub struct MyStruct { pub my_int: i32, pub my_bool: bool, pub my_nullable_enum: Option, } #[derive(Serialize)] pub enum MyEnum { StringNewType(String), StructVariant { floats: Vec }, } fn main() { let schema = schema_for_value!(MyStruct { my_int: 123, my_bool: true, my_nullable_enum: Some(MyEnum::StringNewType("foo".to_string())) }); println!("{}", serde_json::to_string_pretty(&schema).unwrap()); } schemars-0.8.16/examples/from_value.schema.json000064400000000000000000000006110072674642500176620ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyStruct", "examples": [ { "my_bool": true, "my_int": 123, "my_nullable_enum": { "StringNewType": "foo" } } ], "type": "object", "properties": { "my_bool": { "type": "boolean" }, "my_int": { "type": "integer" }, "my_nullable_enum": true } } schemars-0.8.16/examples/main.rs000064400000000000000000000006260072674642500146710ustar 00000000000000use schemars::{schema_for, JsonSchema}; #[derive(JsonSchema)] pub struct MyStruct { pub my_int: i32, pub my_bool: bool, pub my_nullable_enum: Option, } #[derive(JsonSchema)] pub enum MyEnum { StringNewType(String), StructVariant { floats: Vec }, } fn main() { let schema = schema_for!(MyStruct); println!("{}", serde_json::to_string_pretty(&schema).unwrap()); } schemars-0.8.16/examples/main.schema.json000064400000000000000000000025550072674642500164600ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyStruct", "type": "object", "required": [ "my_bool", "my_int" ], "properties": { "my_bool": { "type": "boolean" }, "my_int": { "type": "integer", "format": "int32" }, "my_nullable_enum": { "anyOf": [ { "$ref": "#/definitions/MyEnum" }, { "type": "null" } ] } }, "definitions": { "MyEnum": { "oneOf": [ { "type": "object", "required": [ "StringNewType" ], "properties": { "StringNewType": { "type": "string" } }, "additionalProperties": false }, { "type": "object", "required": [ "StructVariant" ], "properties": { "StructVariant": { "type": "object", "required": [ "floats" ], "properties": { "floats": { "type": "array", "items": { "type": "number", "format": "float" } } } } }, "additionalProperties": false } ] } } } schemars-0.8.16/examples/remote_derive.rs000064400000000000000000000024370072674642500166000ustar 00000000000000// Pretend that this is somebody else's crate, not a module. mod other_crate { // Neither Schemars nor the other crate provides a JsonSchema impl // for this struct. pub struct Duration { pub secs: i64, pub nanos: i32, } } //////////////////////////////////////////////////////////////////////////////// use other_crate::Duration; use schemars::{schema_for, JsonSchema}; // This is just a copy of the remote data structure that Schemars can use to // create a suitable JsonSchema impl. #[derive(JsonSchema)] #[serde(remote = "Duration")] pub struct DurationDef { pub secs: i64, pub nanos: i32, } // Now the remote type can be used almost like it had its own JsonSchema impl // all along. The `with` attribute gives the path to the definition for the // remote type. Note that the real type of the field is the remote type, not // the definition type. #[derive(JsonSchema)] pub struct Process { pub command_line: String, #[serde(with = "DurationDef")] pub wall_time: Duration, // Generic types must be explicitly specified with turbofix `::<>` syntax. #[serde(with = "Vec::")] pub durations: Vec, } fn main() { let schema = schema_for!(Process); println!("{}", serde_json::to_string_pretty(&schema).unwrap()); } schemars-0.8.16/examples/remote_derive.schema.json000064400000000000000000000013740072674642500203630ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Process", "type": "object", "required": [ "command_line", "durations", "wall_time" ], "properties": { "command_line": { "type": "string" }, "durations": { "type": "array", "items": { "$ref": "#/definitions/Duration" } }, "wall_time": { "$ref": "#/definitions/Duration" } }, "definitions": { "Duration": { "type": "object", "required": [ "nanos", "secs" ], "properties": { "nanos": { "type": "integer", "format": "int32" }, "secs": { "type": "integer", "format": "int64" } } } } } schemars-0.8.16/examples/schemars_attrs.rs000064400000000000000000000015360072674642500167700ustar 00000000000000use schemars::{schema_for, JsonSchema}; use serde::{Deserialize, Serialize}; #[derive(Deserialize, Serialize, JsonSchema)] #[schemars(rename_all = "camelCase", deny_unknown_fields)] pub struct MyStruct { #[serde(rename = "thisIsOverridden")] #[schemars(rename = "myNumber", range(min = 1, max = 10))] pub my_int: i32, pub my_bool: bool, #[schemars(default)] pub my_nullable_enum: Option, #[schemars(inner(regex(pattern = "^x$")))] pub my_vec_str: Vec, } #[derive(Deserialize, Serialize, JsonSchema)] #[schemars(untagged)] pub enum MyEnum { StringNewType(#[schemars(phone)] String), StructVariant { #[schemars(length(min = 1, max = 100))] floats: Vec, }, } fn main() { let schema = schema_for!(MyStruct); println!("{}", serde_json::to_string_pretty(&schema).unwrap()); } schemars-0.8.16/examples/schemars_attrs.schema.json000064400000000000000000000023150072674642500205500ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyStruct", "type": "object", "required": [ "myBool", "myNumber", "myVecStr" ], "properties": { "myBool": { "type": "boolean" }, "myNullableEnum": { "default": null, "anyOf": [ { "$ref": "#/definitions/MyEnum" }, { "type": "null" } ] }, "myNumber": { "type": "integer", "format": "int32", "maximum": 10.0, "minimum": 1.0 }, "myVecStr": { "type": "array", "items": { "type": "string", "pattern": "^x$" } } }, "additionalProperties": false, "definitions": { "MyEnum": { "anyOf": [ { "type": "string", "format": "phone" }, { "type": "object", "required": [ "floats" ], "properties": { "floats": { "type": "array", "items": { "type": "number", "format": "float" }, "maxItems": 100, "minItems": 1 } } } ] } } } schemars-0.8.16/examples/serde_attrs.rs000064400000000000000000000011560072674642500162630ustar 00000000000000use schemars::{schema_for, JsonSchema}; use serde::{Deserialize, Serialize}; #[derive(Deserialize, Serialize, JsonSchema)] #[serde(rename_all = "camelCase", deny_unknown_fields)] pub struct MyStruct { #[serde(rename = "myNumber")] pub my_int: i32, pub my_bool: bool, #[serde(default)] pub my_nullable_enum: Option, } #[derive(Deserialize, Serialize, JsonSchema)] #[serde(untagged)] pub enum MyEnum { StringNewType(String), StructVariant { floats: Vec }, } fn main() { let schema = schema_for!(MyStruct); println!("{}", serde_json::to_string_pretty(&schema).unwrap()); } schemars-0.8.16/examples/serde_attrs.schema.json000064400000000000000000000016730072674642500200530ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyStruct", "type": "object", "required": [ "myBool", "myNumber" ], "properties": { "myBool": { "type": "boolean" }, "myNullableEnum": { "default": null, "anyOf": [ { "$ref": "#/definitions/MyEnum" }, { "type": "null" } ] }, "myNumber": { "type": "integer", "format": "int32" } }, "additionalProperties": false, "definitions": { "MyEnum": { "anyOf": [ { "type": "string" }, { "type": "object", "required": [ "floats" ], "properties": { "floats": { "type": "array", "items": { "type": "number", "format": "float" } } } } ] } } } schemars-0.8.16/examples/validate.rs000064400000000000000000000010520072674642500155300ustar 00000000000000use 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, } #[derive(JsonSchema)] pub enum MyEnum { StringNewType(#[validate(phone)] String), StructVariant { #[validate(length(min = 1, max = 100))] floats: Vec, }, } fn main() { let schema = schema_for!(MyStruct); println!("{}", serde_json::to_string_pretty(&schema).unwrap()); } schemars-0.8.16/examples/validate.schema.json000064400000000000000000000025450072674642500173240ustar 00000000000000{ "$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 } ] } } } schemars-0.8.16/src/_private.rs000064400000000000000000000036130072674642500145260ustar 00000000000000use crate::flatten::Merge; use crate::gen::SchemaGenerator; use crate::schema::{Metadata, Schema, SchemaObject}; use crate::JsonSchema; use serde::Serialize; use serde_json::Value; // Helper for generating schemas for flattened `Option` fields. pub fn json_schema_for_flatten( gen: &mut SchemaGenerator, required: bool, ) -> Schema { let mut schema = T::_schemars_private_non_optional_json_schema(gen); if T::_schemars_private_is_option() && !required { if let Schema::Object(SchemaObject { object: Some(ref mut object_validation), .. }) = schema { object_validation.required.clear(); } } schema } pub fn apply_metadata(schema: Schema, metadata: Metadata) -> Schema { if metadata == Metadata::default() { schema } else { let mut schema_obj = schema.into_object(); schema_obj.metadata = Some(Box::new(metadata)).merge(schema_obj.metadata); Schema::Object(schema_obj) } } /// Hack to simulate specialization: /// `MaybeSerializeWrapper(x).maybe_to_value()` will resolve to either /// - The inherent method `MaybeSerializeWrapper::maybe_to_value(...)` if x is `Serialize` /// - The trait method `NoSerialize::maybe_to_value(...)` from the blanket impl otherwise #[doc(hidden)] #[macro_export] macro_rules! _schemars_maybe_to_value { ($expression:expr) => {{ #[allow(unused_imports)] use $crate::_private::{MaybeSerializeWrapper, NoSerialize as _}; MaybeSerializeWrapper($expression).maybe_to_value() }}; } pub struct MaybeSerializeWrapper(pub T); pub trait NoSerialize: Sized { fn maybe_to_value(self) -> Option { None } } impl NoSerialize for T {} impl MaybeSerializeWrapper { pub fn maybe_to_value(self) -> Option { serde_json::value::to_value(self.0).ok() } } schemars-0.8.16/src/flatten.rs000064400000000000000000000121110072674642500143430ustar 00000000000000use crate::schema::*; use crate::{Map, Set}; impl Schema { /// This function is only public for use by schemars_derive. /// /// It should not be considered part of the public API. #[doc(hidden)] pub fn flatten(self, other: Self) -> Schema { if is_null_type(&self) { return other; } else if is_null_type(&other) { return self; } let s1: SchemaObject = self.into(); let s2: SchemaObject = other.into(); Schema::Object(s1.merge(s2)) } } pub(crate) trait Merge: Sized { fn merge(self, other: Self) -> Self; } macro_rules! impl_merge { ($ty:ident { merge: $($merge_field:ident)*, or: $($or_field:ident)*, }) => { impl Merge for $ty { fn merge(self, other: Self) -> Self { $ty { $($merge_field: self.$merge_field.merge(other.$merge_field),)* $($or_field: self.$or_field.or(other.$or_field),)* } } } }; ($ty:ident { or: $($or_field:ident)*, }) => { impl_merge!( $ty { merge: , or: $($or_field)*, }); }; } // For ObjectValidation::additional_properties. impl Merge for Option> { fn merge(self, other: Self) -> Self { match (self.map(|x| *x), other.map(|x| *x)) { // Perfer permissive schemas. (Some(Schema::Bool(true)), _) => Some(Box::new(true.into())), (_, Some(Schema::Bool(true))) => Some(Box::new(true.into())), (None, _) => None, (_, None) => None, // Merge if we have two non-trivial schemas. (Some(Schema::Object(s1)), Some(Schema::Object(s2))) => { Some(Box::new(Schema::Object(s1.merge(s2)))) } // Perfer the more permissive schema. (Some(s1 @ Schema::Object(_)), Some(Schema::Bool(false))) => Some(Box::new(s1)), (Some(Schema::Bool(false)), Some(s2 @ Schema::Object(_))) => Some(Box::new(s2)), // Default to the null schema. (Some(Schema::Bool(false)), Some(Schema::Bool(false))) => Some(Box::new(false.into())), } } } impl_merge!(SchemaObject { merge: extensions instance_type enum_values metadata subschemas number string array object, or: format const_value reference, }); impl Merge for Metadata { fn merge(self, other: Self) -> Self { Metadata { id: self.id.or(other.id), title: self.title.or(other.title), description: self.description.or(other.description), default: self.default.or(other.default), deprecated: self.deprecated || other.deprecated, read_only: self.read_only || other.read_only, write_only: self.write_only || other.write_only, examples: self.examples.merge(other.examples), } } } impl_merge!(SubschemaValidation { or: all_of any_of one_of not if_schema then_schema else_schema, }); impl_merge!(NumberValidation { or: multiple_of maximum exclusive_maximum minimum exclusive_minimum, }); impl_merge!(StringValidation { or: max_length min_length pattern, }); impl_merge!(ArrayValidation { or: items additional_items max_items min_items unique_items contains, }); impl_merge!(ObjectValidation { merge: required properties pattern_properties additional_properties, or: max_properties min_properties property_names, }); impl Merge for Option { fn merge(self, other: Self) -> Self { match (self, other) { (Some(x), Some(y)) => Some(x.merge(y)), (None, y) => y, (x, None) => x, } } } impl Merge for Box { fn merge(mut self, other: Self) -> Self { *self = (*self).merge(*other); self } } impl Merge for Vec { fn merge(mut self, other: Self) -> Self { self.extend(other); self } } impl Merge for Map where K: std::hash::Hash + Eq + Ord, { fn merge(mut self, other: Self) -> Self { self.extend(other); self } } impl Merge for Set { fn merge(mut self, other: Self) -> Self { self.extend(other); self } } impl Merge for SingleOrVec { fn merge(self, other: Self) -> Self { if self == other { return self; } let mut vec = match (self, other) { (SingleOrVec::Vec(v1), SingleOrVec::Vec(v2)) => v1.merge(v2), (SingleOrVec::Vec(mut v), SingleOrVec::Single(s)) | (SingleOrVec::Single(s), SingleOrVec::Vec(mut v)) => { v.push(*s); v } (SingleOrVec::Single(s1), SingleOrVec::Single(s2)) => vec![*s1, *s2], }; vec.sort(); vec.dedup(); SingleOrVec::Vec(vec) } } fn is_null_type(schema: &Schema) -> bool { let s = match schema { Schema::Object(s) => s, _ => return false, }; let instance_type = match &s.instance_type { Some(SingleOrVec::Single(t)) => t, _ => return false, }; **instance_type == InstanceType::Null } schemars-0.8.16/src/gen.rs000064400000000000000000000446400072674642500134730ustar 00000000000000/*! JSON Schema generator and settings. This module is useful if you want more control over how the schema generated than the [`schema_for!`] macro gives you. There are two main types in this module: * [`SchemaSettings`], which defines what JSON Schema features should be used when generating schemas (for example, how `Option`s should be represented). * [`SchemaGenerator`], which manages the generation of a schema document. */ use crate::schema::*; use crate::{visit::*, JsonSchema, Map}; use dyn_clone::DynClone; use serde::Serialize; use std::borrow::Cow; use std::collections::HashMap; use std::{any::Any, collections::HashSet, fmt::Debug}; /// Settings to customize how Schemas are generated. /// /// The default settings currently conform to [JSON Schema Draft 7](https://json-schema.org/specification-links.html#draft-7), but this is liable to change in a future version of Schemars if support for other JSON Schema versions is added. /// If you require your generated schemas to conform to draft 7, consider using the [`draft07`](#method.draft07) method. #[derive(Debug, Clone)] #[non_exhaustive] pub struct SchemaSettings { /// If `true`, schemas for [`Option`](Option) will include a `nullable` property. /// /// This is not part of the JSON Schema spec, but is used in Swagger/OpenAPI schemas. /// /// Defaults to `false`. pub option_nullable: bool, /// If `true`, schemas for [`Option`](Option) will have `null` added to their [`type`](../schema/struct.SchemaObject.html#structfield.instance_type). /// /// Defaults to `true`. pub option_add_null_type: bool, /// A JSON pointer to the expected location of referenceable subschemas within the resulting root schema. /// /// Defaults to `"#/definitions/"`. pub definitions_path: String, /// The URI of the meta-schema describing the structure of the generated schemas. /// /// Defaults to `"http://json-schema.org/draft-07/schema#"`. pub meta_schema: Option, /// A list of visitors that get applied to all generated root schemas. pub visitors: Vec>, /// Inline all subschemas instead of using references. /// /// Some references may still be generated in schemas for recursive types. /// /// Defaults to `false`. pub inline_subschemas: bool, } impl Default for SchemaSettings { fn default() -> SchemaSettings { SchemaSettings::draft07() } } impl SchemaSettings { /// Creates `SchemaSettings` that conform to [JSON Schema Draft 7](https://json-schema.org/specification-links.html#draft-7). pub fn draft07() -> SchemaSettings { SchemaSettings { option_nullable: false, option_add_null_type: true, definitions_path: "#/definitions/".to_owned(), meta_schema: Some("http://json-schema.org/draft-07/schema#".to_owned()), visitors: vec![Box::new(RemoveRefSiblings)], inline_subschemas: false, } } /// Creates `SchemaSettings` that conform to [JSON Schema 2019-09](https://json-schema.org/specification-links.html#2019-09-formerly-known-as-draft-8). pub fn draft2019_09() -> SchemaSettings { SchemaSettings { option_nullable: false, option_add_null_type: true, definitions_path: "#/definitions/".to_owned(), meta_schema: Some("https://json-schema.org/draft/2019-09/schema".to_owned()), visitors: Vec::default(), inline_subschemas: false, } } /// Creates `SchemaSettings` that conform to [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject). pub fn openapi3() -> SchemaSettings { SchemaSettings { option_nullable: true, option_add_null_type: false, definitions_path: "#/components/schemas/".to_owned(), meta_schema: Some( "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema" .to_owned(), ), visitors: vec![ Box::new(RemoveRefSiblings), Box::new(ReplaceBoolSchemas { skip_additional_properties: true, }), Box::new(SetSingleExample { retain_examples: false, }), ], inline_subschemas: false, } } /// Modifies the `SchemaSettings` by calling the given function. /// /// # Example /// ``` /// use schemars::gen::{SchemaGenerator, SchemaSettings}; /// /// let settings = SchemaSettings::default().with(|s| { /// s.option_nullable = true; /// s.option_add_null_type = false; /// }); /// let gen = settings.into_generator(); /// ``` pub fn with(mut self, configure_fn: impl FnOnce(&mut Self)) -> Self { configure_fn(&mut self); self } /// Appends the given visitor to the list of [visitors](SchemaSettings::visitors) for these `SchemaSettings`. pub fn with_visitor(mut self, visitor: impl Visitor + Debug + Clone + 'static) -> Self { self.visitors.push(Box::new(visitor)); self } /// Creates a new [`SchemaGenerator`] using these settings. pub fn into_generator(self) -> SchemaGenerator { SchemaGenerator::new(self) } } /// The main type used to generate JSON Schemas. /// /// # Example /// ``` /// use schemars::{JsonSchema, gen::SchemaGenerator}; /// /// #[derive(JsonSchema)] /// struct MyStruct { /// foo: i32, /// } /// /// let gen = SchemaGenerator::default(); /// let schema = gen.into_root_schema_for::(); /// ``` #[derive(Debug, Default)] pub struct SchemaGenerator { settings: SchemaSettings, definitions: Map, pending_schema_ids: HashSet>, schema_id_to_name: HashMap, String>, used_schema_names: HashSet, } impl Clone for SchemaGenerator { fn clone(&self) -> Self { Self { settings: self.settings.clone(), definitions: self.definitions.clone(), pending_schema_ids: HashSet::new(), schema_id_to_name: HashMap::new(), used_schema_names: HashSet::new(), } } } impl From for SchemaGenerator { fn from(settings: SchemaSettings) -> Self { settings.into_generator() } } impl SchemaGenerator { /// Creates a new `SchemaGenerator` using the given settings. pub fn new(settings: SchemaSettings) -> SchemaGenerator { SchemaGenerator { settings, ..Default::default() } } /// Borrows the [`SchemaSettings`] being used by this `SchemaGenerator`. /// /// # Example /// ``` /// use schemars::gen::SchemaGenerator; /// /// let gen = SchemaGenerator::default(); /// let settings = gen.settings(); /// /// assert_eq!(settings.option_add_null_type, true); /// ``` pub fn settings(&self) -> &SchemaSettings { &self.settings } #[deprecated = "This method no longer has any effect."] pub fn make_extensible(&self, _schema: &mut SchemaObject) {} #[deprecated = "Use `Schema::Bool(true)` instead"] pub fn schema_for_any(&self) -> Schema { Schema::Bool(true) } #[deprecated = "Use `Schema::Bool(false)` instead"] pub fn schema_for_none(&self) -> Schema { Schema::Bool(false) } /// Generates a JSON Schema for the type `T`, and returns either the schema itself or a `$ref` schema referencing `T`'s schema. /// /// If `T` is [referenceable](JsonSchema::is_referenceable), this will add `T`'s schema to this generator's definitions, and /// return a `$ref` schema referencing that schema. Otherwise, this method behaves identically to [`JsonSchema::json_schema`]. /// /// If `T`'s schema depends on any [referenceable](JsonSchema::is_referenceable) schemas, then this method will /// add them to the `SchemaGenerator`'s schema definitions. pub fn subschema_for(&mut self) -> Schema { let id = T::schema_id(); let return_ref = T::is_referenceable() && (!self.settings.inline_subschemas || self.pending_schema_ids.contains(&id)); if return_ref { let name = match self.schema_id_to_name.get(&id).cloned() { Some(n) => n, None => { let base_name = T::schema_name(); let mut name = String::new(); if self.used_schema_names.contains(&base_name) { for i in 2.. { name = format!("{}{}", base_name, i); if !self.used_schema_names.contains(&name) { break; } } } else { name = base_name; } self.used_schema_names.insert(name.clone()); self.schema_id_to_name.insert(id.clone(), name.clone()); name } }; let reference = format!("{}{}", self.settings.definitions_path, name); if !self.definitions.contains_key(&name) { self.insert_new_subschema_for::(name, id); } Schema::new_ref(reference) } else { self.json_schema_internal::(id) } } fn insert_new_subschema_for( &mut self, name: String, id: Cow<'static, str>, ) { let dummy = Schema::Bool(false); // insert into definitions BEFORE calling json_schema to avoid infinite recursion self.definitions.insert(name.clone(), dummy); let schema = self.json_schema_internal::(id); self.definitions.insert(name, schema); } /// Borrows the collection of all [referenceable](JsonSchema::is_referenceable) schemas that have been generated. /// /// The keys of the returned `Map` are the [schema names](JsonSchema::schema_name), and the values are the schemas /// themselves. pub fn definitions(&self) -> &Map { &self.definitions } /// Mutably borrows the collection of all [referenceable](JsonSchema::is_referenceable) schemas that have been generated. /// /// The keys of the returned `Map` are the [schema names](JsonSchema::schema_name), and the values are the schemas /// themselves. pub fn definitions_mut(&mut self) -> &mut Map { &mut self.definitions } /// Returns the collection of all [referenceable](JsonSchema::is_referenceable) schemas that have been generated, /// leaving an empty map in its place. /// /// The keys of the returned `Map` are the [schema names](JsonSchema::schema_name), and the values are the schemas /// themselves. pub fn take_definitions(&mut self) -> Map { std::mem::take(&mut self.definitions) } /// Returns an iterator over the [visitors](SchemaSettings::visitors) being used by this `SchemaGenerator`. pub fn visitors_mut(&mut self) -> impl Iterator { self.settings.visitors.iter_mut().map(|v| v.as_mut()) } /// Generates a root JSON Schema for the type `T`. /// /// If `T`'s schema depends on any [referenceable](JsonSchema::is_referenceable) schemas, then this method will /// add them to the `SchemaGenerator`'s schema definitions and include them in the returned `SchemaObject`'s /// [`definitions`](../schema/struct.Metadata.html#structfield.definitions) pub fn root_schema_for(&mut self) -> RootSchema { let mut schema = self.json_schema_internal::(T::schema_id()).into_object(); schema.metadata().title.get_or_insert_with(T::schema_name); let mut root = RootSchema { meta_schema: self.settings.meta_schema.clone(), definitions: self.definitions.clone(), schema, }; for visitor in &mut self.settings.visitors { visitor.visit_root_schema(&mut root) } root } /// Consumes `self` and generates a root JSON Schema for the type `T`. /// /// If `T`'s schema depends on any [referenceable](JsonSchema::is_referenceable) schemas, then this method will /// include them in the returned `SchemaObject`'s [`definitions`](../schema/struct.Metadata.html#structfield.definitions) pub fn into_root_schema_for(mut self) -> RootSchema { let mut schema = self.json_schema_internal::(T::schema_id()).into_object(); schema.metadata().title.get_or_insert_with(T::schema_name); let mut root = RootSchema { meta_schema: self.settings.meta_schema, definitions: self.definitions, schema, }; for visitor in &mut self.settings.visitors { visitor.visit_root_schema(&mut root) } root } /// Generates a root JSON Schema for the given example value. /// /// If the value implements [`JsonSchema`](crate::JsonSchema), then prefer using the [`root_schema_for()`](Self::root_schema_for()) /// function which will generally produce a more precise schema, particularly when the value contains any enums. pub fn root_schema_for_value( &mut self, value: &T, ) -> Result { let mut schema = value .serialize(crate::ser::Serializer { gen: self, include_title: true, })? .into_object(); if let Ok(example) = serde_json::to_value(value) { schema.metadata().examples.push(example); } let mut root = RootSchema { meta_schema: self.settings.meta_schema.clone(), definitions: self.definitions.clone(), schema, }; for visitor in &mut self.settings.visitors { visitor.visit_root_schema(&mut root) } Ok(root) } /// Consumes `self` and generates a root JSON Schema for the given example value. /// /// If the value implements [`JsonSchema`](crate::JsonSchema), then prefer using the [`into_root_schema_for()!`](Self::into_root_schema_for()) /// function which will generally produce a more precise schema, particularly when the value contains any enums. pub fn into_root_schema_for_value( mut self, value: &T, ) -> Result { let mut schema = value .serialize(crate::ser::Serializer { gen: &mut self, include_title: true, })? .into_object(); if let Ok(example) = serde_json::to_value(value) { schema.metadata().examples.push(example); } let mut root = RootSchema { meta_schema: self.settings.meta_schema, definitions: self.definitions, schema, }; for visitor in &mut self.settings.visitors { visitor.visit_root_schema(&mut root) } Ok(root) } /// Attemps to find the schema that the given `schema` is referencing. /// /// If the given `schema` has a [`$ref`](../schema/struct.SchemaObject.html#structfield.reference) property which refers /// to another schema in `self`'s schema definitions, the referenced schema will be returned. Otherwise, returns `None`. /// /// # Example /// ``` /// use schemars::{JsonSchema, gen::SchemaGenerator}; /// /// #[derive(JsonSchema)] /// struct MyStruct { /// foo: i32, /// } /// /// let mut gen = SchemaGenerator::default(); /// let ref_schema = gen.subschema_for::(); /// /// assert!(ref_schema.is_ref()); /// /// let dereferenced = gen.dereference(&ref_schema); /// /// assert!(dereferenced.is_some()); /// assert!(!dereferenced.unwrap().is_ref()); /// assert_eq!(dereferenced, gen.definitions().get("MyStruct")); /// ``` pub fn dereference<'a>(&'a self, schema: &Schema) -> Option<&'a Schema> { match schema { Schema::Object(SchemaObject { reference: Some(ref schema_ref), .. }) => { let definitions_path = &self.settings().definitions_path; if schema_ref.starts_with(definitions_path) { let name = &schema_ref[definitions_path.len()..]; self.definitions.get(name) } else { None } } _ => None, } } fn json_schema_internal(&mut self, id: Cow<'static, str>) -> Schema { struct PendingSchemaState<'a> { gen: &'a mut SchemaGenerator, id: Cow<'static, str>, did_add: bool, } impl<'a> PendingSchemaState<'a> { fn new(gen: &'a mut SchemaGenerator, id: Cow<'static, str>) -> Self { let did_add = gen.pending_schema_ids.insert(id.clone()); Self { gen, id, did_add } } } impl Drop for PendingSchemaState<'_> { fn drop(&mut self) { if self.did_add { self.gen.pending_schema_ids.remove(&self.id); } } } let pss = PendingSchemaState::new(self, id); T::json_schema(pss.gen) } } /// A [Visitor](Visitor) which implements additional traits required to be included in a [SchemaSettings]. /// /// You will rarely need to use this trait directly as it is automatically implemented for any type which implements all of: /// - [`Visitor`] /// - [`std::fmt::Debug`] /// - [`std::any::Any`] (implemented for all `'static` types) /// - [`std::clone::Clone`] /// /// # Example /// ``` /// use schemars::visit::Visitor; /// use schemars::gen::GenVisitor; /// /// #[derive(Debug, Clone)] /// struct MyVisitor; /// /// impl Visitor for MyVisitor { } /// /// let v: &dyn GenVisitor = &MyVisitor; /// assert!(v.as_any().is::()); /// ``` pub trait GenVisitor: Visitor + Debug + DynClone + Any { /// Upcasts this visitor into an `Any`, which can be used to inspect and manipulate it as its concrete type. fn as_any(&self) -> &dyn Any; } dyn_clone::clone_trait_object!(GenVisitor); impl GenVisitor for T where T: Visitor + Debug + Clone + Any, { fn as_any(&self) -> &dyn Any { self } } schemars-0.8.16/src/json_schema_impls/array.rs000064400000000000000000000056670072674642500175430ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use std::borrow::Cow; // Does not require T: JsonSchema. impl JsonSchema for [T; 0] { no_ref_schema!(); fn schema_name() -> String { "EmptyArray".to_owned() } fn schema_id() -> Cow<'static, str> { Cow::Borrowed("[]") } fn json_schema(_: &mut SchemaGenerator) -> Schema { SchemaObject { instance_type: Some(InstanceType::Array.into()), array: Some(Box::new(ArrayValidation { max_items: Some(0), ..Default::default() })), ..Default::default() } .into() } } macro_rules! array_impls { ($($len:tt)+) => { $( impl JsonSchema for [T; $len] { no_ref_schema!(); fn schema_name() -> String { format!("Array_size_{}_of_{}", $len, T::schema_name()) } fn schema_id() -> Cow<'static, str> { Cow::Owned( format!("[{}; {}]", $len, T::schema_id())) } 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: Some($len), min_items: Some($len), ..Default::default() })), ..Default::default() } .into() } } )+ } } array_impls! { 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 } #[cfg(test)] mod tests { use super::*; use crate::tests::{schema_for, schema_object_for}; use pretty_assertions::assert_eq; #[test] fn schema_for_array() { let schema = schema_object_for::<[i32; 8]>(); assert_eq!( schema.instance_type, Some(SingleOrVec::from(InstanceType::Array)) ); let array_validation = schema.array.unwrap(); assert_eq!( array_validation.items, Some(SingleOrVec::from(schema_for::())) ); assert_eq!(array_validation.max_items, Some(8)); assert_eq!(array_validation.min_items, Some(8)); } // SomeStruct does not implement JsonSchema struct SomeStruct; #[test] fn schema_for_empty_array() { let schema = schema_object_for::<[SomeStruct; 0]>(); assert_eq!( schema.instance_type, Some(SingleOrVec::from(InstanceType::Array)) ); let array_validation = schema.array.unwrap(); assert_eq!(array_validation.max_items, Some(0)); } } schemars-0.8.16/src/json_schema_impls/arrayvec05.rs000064400000000000000000000020610072674642500203670ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; 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 // know max length in bytes. forward_impl!(( JsonSchema for ArrayString where A: Array + Copy) => String); impl JsonSchema for ArrayVec where A::Item: JsonSchema, { no_ref_schema!(); fn schema_name() -> String { format!( "Array_up_to_size_{}_of_{}", A::CAPACITY, A::Item::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: A::CAPACITY.try_into().ok(), ..Default::default() })), ..Default::default() } .into() } } schemars-0.8.16/src/json_schema_impls/arrayvec07.rs000064400000000000000000000017320072674642500203750ustar 00000000000000use 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() } } schemars-0.8.16/src/json_schema_impls/atomic.rs000064400000000000000000000022370072674642500176670ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use std::sync::atomic::*; forward_impl!(AtomicBool => bool); forward_impl!(AtomicI8 => i8); forward_impl!(AtomicI16 => i16); forward_impl!(AtomicI32 => i32); #[cfg(std_atomic64)] forward_impl!(AtomicI64 => i64); forward_impl!(AtomicIsize => isize); forward_impl!(AtomicU8 => u8); forward_impl!(AtomicU16 => u16); forward_impl!(AtomicU32 => u32); #[cfg(std_atomic64)] forward_impl!(AtomicU64 => u64); forward_impl!(AtomicUsize => usize); #[cfg(test)] mod tests { use super::*; use crate::tests::schema_object_for; use pretty_assertions::assert_eq; #[test] fn schema_for_atomics() { let atomic_schema = schema_object_for::<( AtomicBool, AtomicI8, AtomicI16, AtomicI32, AtomicI64, AtomicIsize, AtomicU8, AtomicU16, AtomicU32, AtomicU64, AtomicUsize, )>(); let basic_schema = schema_object_for::<(bool, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize)>(); assert_eq!(atomic_schema, basic_schema); } } schemars-0.8.16/src/json_schema_impls/bytes.rs000064400000000000000000000003240072674642500175340ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use bytes::{Bytes, BytesMut}; forward_impl!((JsonSchema for Bytes) => Vec); forward_impl!((JsonSchema for BytesMut) => Vec); schemars-0.8.16/src/json_schema_impls/chrono.rs000064400000000000000000000035440072674642500177050ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use chrono::prelude::*; use serde_json::json; use std::borrow::Cow; impl JsonSchema for Weekday { no_ref_schema!(); fn schema_name() -> String { "Weekday".to_owned() } fn schema_id() -> Cow<'static, str> { Cow::Borrowed("chrono::Weekday") } fn json_schema(_: &mut SchemaGenerator) -> Schema { SchemaObject { instance_type: Some(InstanceType::String.into()), enum_values: Some(vec![ json!("Mon"), json!("Tue"), json!("Wed"), json!("Thu"), json!("Fri"), json!("Sat"), json!("Sun"), ]), ..Default::default() } .into() } } macro_rules! formatted_string_impl { ($ty:ident, $format:literal) => { formatted_string_impl!($ty, $format, JsonSchema for $ty); }; ($ty:ident, $format:literal, $($desc:tt)+) => { impl $($desc)+ { no_ref_schema!(); fn schema_name() -> String { stringify!($ty).to_owned() } fn schema_id() -> Cow<'static, str> { Cow::Borrowed(stringify!(chrono::$ty)) } fn json_schema(_: &mut SchemaGenerator) -> Schema { SchemaObject { instance_type: Some(InstanceType::String.into()), format: Some($format.to_owned()), ..Default::default() } .into() } } }; } formatted_string_impl!(NaiveDate, "date"); formatted_string_impl!(NaiveDateTime, "partial-date-time"); formatted_string_impl!(NaiveTime, "partial-date-time"); formatted_string_impl!(DateTime, "date-time", JsonSchema for DateTime); schemars-0.8.16/src/json_schema_impls/core.rs000064400000000000000000000170650072674642500173500ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use serde_json::json; use std::borrow::Cow; use std::ops::{Bound, Range, RangeInclusive}; impl JsonSchema for Option { no_ref_schema!(); fn schema_name() -> String { format!("Nullable_{}", T::schema_name()) } fn schema_id() -> Cow<'static, str> { Cow::Owned(format!("Option<{}>", T::schema_id())) } fn json_schema(gen: &mut SchemaGenerator) -> Schema { let mut schema = gen.subschema_for::(); if gen.settings().option_add_null_type { schema = match schema { Schema::Bool(true) => Schema::Bool(true), Schema::Bool(false) => <()>::json_schema(gen), Schema::Object(SchemaObject { instance_type: Some(ref mut instance_type), .. }) => { add_null_type(instance_type); schema } schema => SchemaObject { // TODO technically the schema already accepts null, so this may be unnecessary subschemas: Some(Box::new(SubschemaValidation { any_of: Some(vec![schema, <()>::json_schema(gen)]), ..Default::default() })), ..Default::default() } .into(), } } if gen.settings().option_nullable { let mut schema_obj = schema.into_object(); schema_obj .extensions .insert("nullable".to_owned(), json!(true)); schema = Schema::Object(schema_obj); }; schema } fn _schemars_private_non_optional_json_schema(gen: &mut SchemaGenerator) -> Schema { T::_schemars_private_non_optional_json_schema(gen) } fn _schemars_private_is_option() -> bool { true } } fn add_null_type(instance_type: &mut SingleOrVec) { match instance_type { SingleOrVec::Single(ty) if **ty != InstanceType::Null => { *instance_type = vec![**ty, InstanceType::Null].into() } SingleOrVec::Vec(ty) if !ty.contains(&InstanceType::Null) => ty.push(InstanceType::Null), _ => {} }; } impl JsonSchema for Result { fn schema_name() -> String { format!("Result_of_{}_or_{}", T::schema_name(), E::schema_name()) } fn schema_id() -> Cow<'static, str> { Cow::Owned(format!("Result<{}, {}>", T::schema_id(), E::schema_id())) } fn json_schema(gen: &mut SchemaGenerator) -> Schema { let mut ok_schema = SchemaObject { instance_type: Some(InstanceType::Object.into()), ..Default::default() }; let obj = ok_schema.object(); obj.required.insert("Ok".to_owned()); obj.properties .insert("Ok".to_owned(), gen.subschema_for::()); let mut err_schema = SchemaObject { instance_type: Some(InstanceType::Object.into()), ..Default::default() }; let obj = err_schema.object(); obj.required.insert("Err".to_owned()); obj.properties .insert("Err".to_owned(), gen.subschema_for::()); let mut schema = SchemaObject::default(); schema.subschemas().one_of = Some(vec![ok_schema.into(), err_schema.into()]); schema.into() } } impl JsonSchema for Bound { fn schema_name() -> String { format!("Bound_of_{}", T::schema_name()) } fn schema_id() -> Cow<'static, str> { Cow::Owned(format!("Bound<{}>", T::schema_id())) } fn json_schema(gen: &mut SchemaGenerator) -> Schema { let mut included_schema = SchemaObject { instance_type: Some(InstanceType::Object.into()), ..Default::default() }; let obj = included_schema.object(); obj.required.insert("Included".to_owned()); obj.properties .insert("Included".to_owned(), gen.subschema_for::()); let mut excluded_schema = SchemaObject { instance_type: Some(InstanceType::Object.into()), ..Default::default() }; let obj = excluded_schema.object(); obj.required.insert("Excluded".to_owned()); obj.properties .insert("Excluded".to_owned(), gen.subschema_for::()); let unbounded_schema = SchemaObject { instance_type: Some(InstanceType::String.into()), const_value: Some(json!("Unbounded")), ..Default::default() }; let mut schema = SchemaObject::default(); schema.subschemas().one_of = Some(vec![ included_schema.into(), excluded_schema.into(), unbounded_schema.into(), ]); schema.into() } } impl JsonSchema for Range { fn schema_name() -> String { format!("Range_of_{}", T::schema_name()) } fn schema_id() -> Cow<'static, str> { Cow::Owned(format!("Range<{}>", T::schema_id())) } fn json_schema(gen: &mut SchemaGenerator) -> Schema { let mut schema = SchemaObject { instance_type: Some(InstanceType::Object.into()), ..Default::default() }; let obj = schema.object(); obj.required.insert("start".to_owned()); obj.required.insert("end".to_owned()); obj.properties .insert("start".to_owned(), gen.subschema_for::()); obj.properties .insert("end".to_owned(), gen.subschema_for::()); schema.into() } } forward_impl!(( JsonSchema for RangeInclusive) => Range); forward_impl!(( JsonSchema for std::marker::PhantomData) => ()); forward_impl!((<'a> JsonSchema for std::fmt::Arguments<'a>) => String); #[cfg(test)] mod tests { use super::*; use crate::tests::{schema_for, schema_object_for}; use pretty_assertions::assert_eq; #[test] fn schema_for_option() { let schema = schema_object_for::>(); assert_eq!( schema.instance_type, Some(vec![InstanceType::Integer, InstanceType::Null].into()) ); assert_eq!(schema.extensions.get("nullable"), None); assert_eq!(schema.subschemas.is_none(), true); } #[test] fn schema_for_option_with_ref() { use crate as schemars; #[derive(JsonSchema)] struct Foo; let schema = schema_object_for::>(); assert_eq!(schema.instance_type, None); assert_eq!(schema.extensions.get("nullable"), None); assert_eq!(schema.subschemas.is_some(), true); let any_of = schema.subschemas.unwrap().any_of.unwrap(); assert_eq!(any_of.len(), 2); assert_eq!(any_of[0], Schema::new_ref("#/definitions/Foo".to_string())); assert_eq!(any_of[1], schema_for::<()>()); } #[test] fn schema_for_result() { let schema = schema_object_for::>(); let one_of = schema.subschemas.unwrap().one_of.unwrap(); assert_eq!(one_of.len(), 2); let ok_schema: SchemaObject = one_of[0].clone().into(); let obj = ok_schema.object.unwrap(); assert!(obj.required.contains("Ok")); assert_eq!(obj.properties["Ok"], schema_for::()); let err_schema: SchemaObject = one_of[1].clone().into(); let obj = err_schema.object.unwrap(); assert!(obj.required.contains("Err")); assert_eq!(obj.properties["Err"], schema_for::()); } } schemars-0.8.16/src/json_schema_impls/decimal.rs000064400000000000000000000021430072674642500200050ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use std::borrow::Cow; macro_rules! decimal_impl { ($type:ty) => { impl JsonSchema for $type { no_ref_schema!(); fn schema_name() -> String { "Decimal".to_owned() } fn schema_id() -> Cow<'static, str> { Cow::Borrowed("Decimal") } fn json_schema(_: &mut SchemaGenerator) -> Schema { SchemaObject { instance_type: Some(InstanceType::String.into()), string: Some(Box::new(StringValidation { pattern: Some(r"^-?[0-9]+(\.[0-9]+)?$".to_owned()), ..Default::default() })), ..Default::default() } .into() } } }; } #[cfg(feature = "rust_decimal")] decimal_impl!(rust_decimal::Decimal); #[cfg(feature = "bigdecimal03")] decimal_impl!(bigdecimal03::BigDecimal); #[cfg(feature = "bigdecimal04")] decimal_impl!(bigdecimal04::BigDecimal); schemars-0.8.16/src/json_schema_impls/either.rs000064400000000000000000000013440072674642500176710ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use either::Either; use std::borrow::Cow; impl JsonSchema for Either { no_ref_schema!(); fn schema_name() -> String { format!("Either_{}_or_{}", L::schema_name(), R::schema_name()) } fn schema_id() -> Cow<'static, str> { Cow::Owned(format!( "either::Either<{}, {}>", L::schema_id(), R::schema_id() )) } fn json_schema(gen: &mut SchemaGenerator) -> Schema { let mut schema = SchemaObject::default(); schema.subschemas().any_of = Some(vec![gen.subschema_for::(), gen.subschema_for::()]); schema.into() } } schemars-0.8.16/src/json_schema_impls/enumset.rs000064400000000000000000000003470072674642500200730ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use enumset::{EnumSet, EnumSetType}; forward_impl!(( JsonSchema for EnumSet where T: EnumSetType + JsonSchema) => std::collections::BTreeSet); schemars-0.8.16/src/json_schema_impls/ffi.rs000064400000000000000000000024750072674642500171630ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use std::borrow::Cow; use std::ffi::{CStr, CString, OsStr, OsString}; impl JsonSchema for OsString { fn schema_name() -> String { "OsString".to_owned() } fn schema_id() -> Cow<'static, str> { Cow::Borrowed("std::ffi::OsString") } fn json_schema(gen: &mut SchemaGenerator) -> Schema { let mut unix_schema = SchemaObject { instance_type: Some(InstanceType::Object.into()), ..Default::default() }; let obj = unix_schema.object(); obj.required.insert("Unix".to_owned()); obj.properties .insert("Unix".to_owned(), >::json_schema(gen)); let mut win_schema = SchemaObject { instance_type: Some(InstanceType::Object.into()), ..Default::default() }; let obj = win_schema.object(); obj.required.insert("Windows".to_owned()); obj.properties .insert("Windows".to_owned(), >::json_schema(gen)); let mut schema = SchemaObject::default(); schema.subschemas().one_of = Some(vec![unix_schema.into(), win_schema.into()]); schema.into() } } forward_impl!(OsStr => OsString); forward_impl!(CString => Vec); forward_impl!(CStr => Vec); schemars-0.8.16/src/json_schema_impls/indexmap.rs000064400000000000000000000005160072674642500202160ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use indexmap::{IndexMap, IndexSet}; use std::collections::{HashMap, HashSet}; forward_impl!(( JsonSchema for IndexMap) => HashMap); forward_impl!(( JsonSchema for IndexSet) => HashSet); schemars-0.8.16/src/json_schema_impls/indexmap2.rs000064400000000000000000000005170072674642500203010ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use indexmap2::{IndexMap, IndexSet}; use std::collections::{HashMap, HashSet}; forward_impl!(( JsonSchema for IndexMap) => HashMap); forward_impl!(( JsonSchema for IndexSet) => HashSet); schemars-0.8.16/src/json_schema_impls/maps.rs000064400000000000000000000022330072674642500173470ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use std::borrow::Cow; macro_rules! map_impl { ($($desc:tt)+) => { impl $($desc)+ where V: JsonSchema, { no_ref_schema!(); fn schema_name() -> String { format!("Map_of_{}", V::schema_name()) } fn schema_id() -> Cow<'static, str> { Cow::Owned(format!("Map<{}>", V::schema_id())) } fn json_schema(gen: &mut SchemaGenerator) -> Schema { let subschema = gen.subschema_for::(); SchemaObject { instance_type: Some(InstanceType::Object.into()), object: Some(Box::new(ObjectValidation { additional_properties: Some(Box::new(subschema)), ..Default::default() })), ..Default::default() } .into() } } }; } map_impl!( JsonSchema for std::collections::BTreeMap); map_impl!( JsonSchema for std::collections::HashMap); schemars-0.8.16/src/json_schema_impls/mod.rs000064400000000000000000000036560072674642500172000ustar 00000000000000macro_rules! no_ref_schema { () => { fn is_referenceable() -> bool { false } }; } macro_rules! forward_impl { (($($impl:tt)+) => $target:ty) => { impl $($impl)+ { fn is_referenceable() -> bool { <$target>::is_referenceable() } fn schema_name() -> String { <$target>::schema_name() } fn schema_id() -> std::borrow::Cow<'static, str> { <$target>::schema_id() } fn json_schema(gen: &mut SchemaGenerator) -> Schema { <$target>::json_schema(gen) } fn _schemars_private_non_optional_json_schema(gen: &mut SchemaGenerator) -> Schema { <$target>::_schemars_private_non_optional_json_schema(gen) } fn _schemars_private_is_option() -> bool { <$target>::_schemars_private_is_option() } } }; ($ty:ty => $target:ty) => { forward_impl!((JsonSchema for $ty) => $target); }; } mod array; #[cfg(feature = "arrayvec05")] mod arrayvec05; #[cfg(feature = "arrayvec07")] mod arrayvec07; #[cfg(std_atomic)] mod atomic; #[cfg(feature = "bytes")] mod bytes; #[cfg(feature = "chrono")] mod chrono; mod core; #[cfg(any( feature = "rust_decimal", feature = "bigdecimal03", feature = "bigdecimal04" ))] mod decimal; #[cfg(feature = "either")] mod either; #[cfg(feature = "enumset")] mod enumset; mod ffi; #[cfg(feature = "indexmap")] mod indexmap; #[cfg(feature = "indexmap2")] mod indexmap2; mod maps; mod nonzero_signed; mod nonzero_unsigned; mod primitives; #[cfg(feature = "semver")] mod semver; mod sequences; mod serdejson; #[cfg(feature = "smallvec")] mod smallvec; #[cfg(feature = "smol_str")] mod smol_str; mod time; mod tuple; #[cfg(feature = "url")] mod url; #[cfg(feature = "uuid08")] mod uuid08; #[cfg(feature = "uuid1")] mod uuid1; mod wrapper; schemars-0.8.16/src/json_schema_impls/nonzero_signed.rs000064400000000000000000000023100072674642500214260ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use std::borrow::Cow; use std::num::*; macro_rules! nonzero_unsigned_impl { ($type:ty => $primitive:ty) => { impl JsonSchema for $type { no_ref_schema!(); fn schema_name() -> String { stringify!($type).to_owned() } fn schema_id() -> Cow<'static, str> { Cow::Borrowed(stringify!(std::num::$type)) } fn json_schema(gen: &mut SchemaGenerator) -> Schema { let zero_schema: Schema = SchemaObject { const_value: Some(0.into()), ..Default::default() } .into(); let mut schema: SchemaObject = <$primitive>::json_schema(gen).into(); schema.subschemas().not = Some(Box::from(zero_schema)); schema.into() } } }; } nonzero_unsigned_impl!(NonZeroI8 => i8); nonzero_unsigned_impl!(NonZeroI16 => i16); nonzero_unsigned_impl!(NonZeroI32 => i32); nonzero_unsigned_impl!(NonZeroI64 => i64); nonzero_unsigned_impl!(NonZeroI128 => i128); nonzero_unsigned_impl!(NonZeroIsize => isize); schemars-0.8.16/src/json_schema_impls/nonzero_unsigned.rs000064400000000000000000000026540072674642500220040ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use std::borrow::Cow; use std::num::*; macro_rules! nonzero_unsigned_impl { ($type:ty => $primitive:ty) => { impl JsonSchema for $type { no_ref_schema!(); fn schema_name() -> String { stringify!($type).to_owned() } fn schema_id() -> Cow<'static, str> { Cow::Borrowed(stringify!(std::num::$type)) } fn json_schema(gen: &mut SchemaGenerator) -> Schema { let mut schema: SchemaObject = <$primitive>::json_schema(gen).into(); schema.number().minimum = Some(1.0); schema.into() } } }; } nonzero_unsigned_impl!(NonZeroU8 => u8); nonzero_unsigned_impl!(NonZeroU16 => u16); nonzero_unsigned_impl!(NonZeroU32 => u32); nonzero_unsigned_impl!(NonZeroU64 => u64); nonzero_unsigned_impl!(NonZeroU128 => u128); nonzero_unsigned_impl!(NonZeroUsize => usize); #[cfg(test)] mod tests { use super::*; use crate::tests::schema_object_for; use pretty_assertions::assert_eq; #[test] fn schema_for_nonzero_u32() { let schema = schema_object_for::(); assert_eq!(schema.number.unwrap().minimum, Some(1.0)); assert_eq!(schema.instance_type, Some(InstanceType::Integer.into())); assert_eq!(schema.format, Some("uint32".to_owned())); } } schemars-0.8.16/src/json_schema_impls/primitives.rs000064400000000000000000000067030072674642500206100ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use std::borrow::Cow; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; use std::path::{Path, PathBuf}; macro_rules! simple_impl { ($type:ty => $instance_type:ident) => { simple_impl!($type => $instance_type, stringify!($instance_type), None); }; ($type:ty => $instance_type:ident, $format:literal) => { simple_impl!($type => $instance_type, $format, Some($format.to_owned())); }; ($type:ty => $instance_type:ident, $name:expr, $format:expr) => { impl JsonSchema for $type { no_ref_schema!(); fn schema_name() -> String { $name.to_owned() } fn schema_id() -> Cow<'static, str> { Cow::Borrowed($name) } fn json_schema(_: &mut SchemaGenerator) -> Schema { SchemaObject { instance_type: Some(InstanceType::$instance_type.into()), format: $format, ..Default::default() } .into() } } }; } simple_impl!(str => String); simple_impl!(String => String); simple_impl!(bool => Boolean); simple_impl!(f32 => Number, "float"); simple_impl!(f64 => Number, "double"); simple_impl!(i8 => Integer, "int8"); simple_impl!(i16 => Integer, "int16"); simple_impl!(i32 => Integer, "int32"); simple_impl!(i64 => Integer, "int64"); simple_impl!(i128 => Integer, "int128"); simple_impl!(isize => Integer, "int"); simple_impl!(() => Null); simple_impl!(Path => String); simple_impl!(PathBuf => String); simple_impl!(Ipv4Addr => String, "ipv4"); simple_impl!(Ipv6Addr => String, "ipv6"); simple_impl!(IpAddr => String, "ip"); simple_impl!(SocketAddr => String); simple_impl!(SocketAddrV4 => String); simple_impl!(SocketAddrV6 => String); macro_rules! unsigned_impl { ($type:ty => $instance_type:ident, $format:expr) => { impl JsonSchema for $type { no_ref_schema!(); fn schema_name() -> String { $format.to_owned() } fn schema_id() -> Cow<'static, str> { Cow::Borrowed($format) } fn json_schema(_: &mut SchemaGenerator) -> Schema { let mut schema = SchemaObject { instance_type: Some(InstanceType::$instance_type.into()), format: Some($format.to_owned()), ..Default::default() }; schema.number().minimum = Some(0.0); schema.into() } } }; } unsigned_impl!(u8 => Integer, "uint8"); unsigned_impl!(u16 => Integer, "uint16"); unsigned_impl!(u32 => Integer, "uint32"); unsigned_impl!(u64 => Integer, "uint64"); unsigned_impl!(u128 => Integer, "uint128"); unsigned_impl!(usize => Integer, "uint"); impl JsonSchema for char { no_ref_schema!(); fn schema_name() -> String { "Character".to_owned() } fn schema_id() -> Cow<'static, str> { Cow::Borrowed("char") } fn json_schema(_: &mut SchemaGenerator) -> Schema { SchemaObject { instance_type: Some(InstanceType::String.into()), string: Some(Box::new(StringValidation { min_length: Some(1), max_length: Some(1), ..Default::default() })), ..Default::default() } .into() } } schemars-0.8.16/src/json_schema_impls/semver.rs000064400000000000000000000017310072674642500177120ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use semver::Version; use std::borrow::Cow; impl JsonSchema for Version { no_ref_schema!(); fn schema_name() -> String { "Version".to_owned() } fn schema_id() -> Cow<'static, str> { Cow::Borrowed("semver::Version") } fn json_schema(_: &mut SchemaGenerator) -> Schema { SchemaObject { instance_type: Some(InstanceType::String.into()), string: Some(Box::new(StringValidation { // https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string pattern: Some(r"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$".to_owned()), ..Default::default() })), ..Default::default() } .into() } } schemars-0.8.16/src/json_schema_impls/sequences.rs000064400000000000000000000044300072674642500204030ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use std::borrow::Cow; macro_rules! seq_impl { ($($desc:tt)+) => { impl $($desc)+ where T: JsonSchema, { no_ref_schema!(); fn schema_name() -> String { format!("Array_of_{}", T::schema_name()) } fn schema_id() -> Cow<'static, str> { Cow::Owned( format!("[{}]", T::schema_id())) } 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()), ..Default::default() })), ..Default::default() } .into() } } }; } macro_rules! set_impl { ($($desc:tt)+) => { impl $($desc)+ where T: JsonSchema, { no_ref_schema!(); fn schema_name() -> String { format!("Set_of_{}", T::schema_name()) } fn schema_id() -> Cow<'static, str> { Cow::Owned( format!("Set<{}>", T::schema_id())) } fn json_schema(gen: &mut SchemaGenerator) -> Schema { SchemaObject { instance_type: Some(InstanceType::Array.into()), array: Some(Box::new(ArrayValidation { unique_items: Some(true), items: Some(gen.subschema_for::().into()), ..Default::default() })), ..Default::default() } .into() } } }; } seq_impl!( JsonSchema for std::collections::BinaryHeap); seq_impl!( JsonSchema for std::collections::LinkedList); seq_impl!( JsonSchema for [T]); seq_impl!( JsonSchema for Vec); seq_impl!( JsonSchema for std::collections::VecDeque); set_impl!( JsonSchema for std::collections::BTreeSet); set_impl!( JsonSchema for std::collections::HashSet); schemars-0.8.16/src/json_schema_impls/serdejson.rs000064400000000000000000000017770072674642500204170ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use serde_json::{Map, Number, Value}; use std::borrow::Cow; use std::collections::BTreeMap; impl JsonSchema for Value { no_ref_schema!(); fn schema_name() -> String { "AnyValue".to_owned() } fn schema_id() -> Cow<'static, str> { Cow::Borrowed("AnyValue") } fn json_schema(_: &mut SchemaGenerator) -> Schema { Schema::Bool(true) } } forward_impl!(Map => BTreeMap); impl JsonSchema for Number { no_ref_schema!(); fn schema_name() -> String { "Number".to_owned() } fn schema_id() -> Cow<'static, str> { Cow::Borrowed("Number") } fn json_schema(_: &mut SchemaGenerator) -> Schema { SchemaObject { instance_type: Some(InstanceType::Number.into()), ..Default::default() } .into() } } #[cfg(feature = "raw_value")] forward_impl!(serde_json::value::RawValue => Value); schemars-0.8.16/src/json_schema_impls/smallvec.rs000064400000000000000000000003220072674642500202120ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use smallvec::{Array, SmallVec}; forward_impl!(( JsonSchema for SmallVec where A::Item: JsonSchema) => Vec); schemars-0.8.16/src/json_schema_impls/smol_str.rs000064400000000000000000000002100072674642500202420ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use smol_str::SmolStr; forward_impl!(SmolStr => String); schemars-0.8.16/src/json_schema_impls/time.rs000064400000000000000000000032070072674642500173470ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use std::borrow::Cow; use std::time::{Duration, SystemTime}; impl JsonSchema for Duration { fn schema_name() -> String { "Duration".to_owned() } fn schema_id() -> Cow<'static, str> { Cow::Borrowed("std::time::Duration") } fn json_schema(gen: &mut SchemaGenerator) -> Schema { let mut schema = SchemaObject { instance_type: Some(InstanceType::Object.into()), ..Default::default() }; let obj = schema.object(); obj.required.insert("secs".to_owned()); obj.required.insert("nanos".to_owned()); obj.properties .insert("secs".to_owned(), ::json_schema(gen)); obj.properties .insert("nanos".to_owned(), ::json_schema(gen)); schema.into() } } impl JsonSchema for SystemTime { fn schema_name() -> String { "SystemTime".to_owned() } fn schema_id() -> Cow<'static, str> { Cow::Borrowed("std::time::SystemTime") } fn json_schema(gen: &mut SchemaGenerator) -> Schema { let mut schema = SchemaObject { instance_type: Some(InstanceType::Object.into()), ..Default::default() }; let obj = schema.object(); obj.required.insert("secs_since_epoch".to_owned()); obj.required.insert("nanos_since_epoch".to_owned()); obj.properties .insert("secs_since_epoch".to_owned(), ::json_schema(gen)); obj.properties .insert("nanos_since_epoch".to_owned(), ::json_schema(gen)); schema.into() } } schemars-0.8.16/src/json_schema_impls/tuple.rs000064400000000000000000000055120072674642500175430ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use std::borrow::Cow; macro_rules! tuple_impls { ($($len:expr => ($($name:ident)+))+) => { $( impl<$($name: JsonSchema),+> JsonSchema for ($($name,)+) { no_ref_schema!(); fn schema_name() -> String { let mut name = "Tuple_of_".to_owned(); name.push_str(&[$($name::schema_name()),+].join("_and_")); name } fn schema_id() -> Cow<'static, str> { let mut id = "(".to_owned(); id.push_str(&[$($name::schema_id()),+].join(",")); id.push(')'); Cow::Owned(id) } fn json_schema(gen: &mut SchemaGenerator) -> Schema { let items = vec![ $(gen.subschema_for::<$name>()),+ ]; SchemaObject { instance_type: Some(InstanceType::Array.into()), array: Some(Box::new(ArrayValidation { items: Some(items.into()), max_items: Some($len), min_items: Some($len), ..Default::default() })), ..Default::default() } .into() } } )+ } } tuple_impls! { 1 => (T0) 2 => (T0 T1) 3 => (T0 T1 T2) 4 => (T0 T1 T2 T3) 5 => (T0 T1 T2 T3 T4) 6 => (T0 T1 T2 T3 T4 T5) 7 => (T0 T1 T2 T3 T4 T5 T6) 8 => (T0 T1 T2 T3 T4 T5 T6 T7) 9 => (T0 T1 T2 T3 T4 T5 T6 T7 T8) 10 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9) 11 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10) 12 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11) 13 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12) 14 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13) 15 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14) 16 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15) } #[cfg(test)] mod tests { use super::*; use crate::tests::{schema_for, schema_object_for}; use pretty_assertions::assert_eq; #[test] fn schema_for_map_any_value() { let schema = schema_object_for::<(i32, bool)>(); assert_eq!( schema.instance_type, Some(SingleOrVec::from(InstanceType::Array)) ); let array_validation = schema.array.unwrap(); assert_eq!( array_validation.items, Some(SingleOrVec::Vec(vec![ schema_for::(), schema_for::() ])) ); assert_eq!(array_validation.max_items, Some(2)); assert_eq!(array_validation.min_items, Some(2)); } } schemars-0.8.16/src/json_schema_impls/url.rs000064400000000000000000000010640072674642500172120ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use std::borrow::Cow; use url::Url; impl JsonSchema for Url { no_ref_schema!(); fn schema_name() -> String { "Url".to_owned() } fn schema_id() -> Cow<'static, str> { Cow::Borrowed("url::Url") } fn json_schema(_: &mut SchemaGenerator) -> Schema { SchemaObject { instance_type: Some(InstanceType::String.into()), format: Some("uri".to_owned()), ..Default::default() } .into() } } schemars-0.8.16/src/json_schema_impls/uuid08.rs000064400000000000000000000010770072674642500175320ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use std::borrow::Cow; use uuid08::Uuid; impl JsonSchema for Uuid { no_ref_schema!(); fn schema_name() -> String { "Uuid".to_string() } fn schema_id() -> Cow<'static, str> { Cow::Borrowed("uuid::Uuid") } fn json_schema(_: &mut SchemaGenerator) -> Schema { SchemaObject { instance_type: Some(InstanceType::String.into()), format: Some("uuid".to_string()), ..Default::default() } .into() } } schemars-0.8.16/src/json_schema_impls/uuid1.rs000064400000000000000000000010760072674642500174420ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use std::borrow::Cow; use uuid1::Uuid; impl JsonSchema for Uuid { no_ref_schema!(); fn schema_name() -> String { "Uuid".to_string() } fn schema_id() -> Cow<'static, str> { Cow::Borrowed("uuid::Uuid") } fn json_schema(_: &mut SchemaGenerator) -> Schema { SchemaObject { instance_type: Some(InstanceType::String.into()), format: Some("uuid".to_string()), ..Default::default() } .into() } } schemars-0.8.16/src/json_schema_impls/wrapper.rs000064400000000000000000000020400072674642500200630ustar 00000000000000use crate::gen::SchemaGenerator; use crate::schema::Schema; use crate::JsonSchema; macro_rules! wrapper_impl { ($($desc:tt)+) => { forward_impl!(($($desc)+ where T: JsonSchema) => T); }; } wrapper_impl!(<'a, T: ?Sized> JsonSchema for &'a T); wrapper_impl!(<'a, T: ?Sized> JsonSchema for &'a mut T); wrapper_impl!( JsonSchema for Box); wrapper_impl!( JsonSchema for std::rc::Rc); wrapper_impl!( JsonSchema for std::rc::Weak); wrapper_impl!( JsonSchema for std::sync::Arc); wrapper_impl!( JsonSchema for std::sync::Weak); wrapper_impl!( JsonSchema for std::sync::Mutex); wrapper_impl!( JsonSchema for std::sync::RwLock); wrapper_impl!( JsonSchema for std::cell::Cell); wrapper_impl!( JsonSchema for std::cell::RefCell); wrapper_impl!(<'a, T: ?Sized + ToOwned> JsonSchema for std::borrow::Cow<'a, T>); wrapper_impl!( JsonSchema for std::num::Wrapping); wrapper_impl!( JsonSchema for std::cmp::Reverse); schemars-0.8.16/src/lib.rs000064400000000000000000000150710072674642500134640ustar 00000000000000#![forbid(unsafe_code)] #![doc = include_str!("../README.md")] /// The map type used by schemars types. /// /// Currently a `BTreeMap` or `IndexMap` can be used, but this may change to a different implementation /// with a similar interface in a future version of schemars. /// The `IndexMap` will be used when the `preserve_order` feature flag is set. #[cfg(not(feature = "preserve_order"))] pub type Map = std::collections::BTreeMap; #[cfg(feature = "preserve_order")] pub type Map = indexmap::IndexMap; /// The set type used by schemars types. /// /// Currently a `BTreeSet`, but this may change to a different implementation /// with a similar interface in a future version of schemars. pub type Set = std::collections::BTreeSet; /// A view into a single entry in a map, which may either be vacant or occupied. // /// This is constructed from the `entry` method on `BTreeMap` or `IndexMap`, /// depending on whether the `preserve_order` feature flag is set. #[cfg(not(feature = "preserve_order"))] pub type MapEntry<'a, K, V> = std::collections::btree_map::Entry<'a, K, V>; #[cfg(feature = "preserve_order")] pub type MapEntry<'a, K, V> = indexmap::map::Entry<'a, K, V>; mod flatten; mod json_schema_impls; mod ser; #[macro_use] mod macros; /// This module is only public for use by `schemars_derive`. It should not need to be used by code /// outside of `schemars`, and should not be considered part of the public API. #[doc(hidden)] pub mod _private; pub mod gen; pub mod schema; pub mod visit; #[cfg(feature = "schemars_derive")] extern crate schemars_derive; use std::borrow::Cow; #[cfg(feature = "schemars_derive")] pub use schemars_derive::*; // Export serde_json so schemars_derive can use it #[doc(hidden)] pub use serde_json as _serde_json; use schema::Schema; /// A type which can be described as a JSON Schema document. /// /// This is implemented for many Rust primitive and standard library types. /// /// This can also be automatically derived on most custom types with `#[derive(JsonSchema)]`. /// /// # Examples /// Deriving an implementation: /// ``` /// use schemars::{schema_for, JsonSchema}; /// /// #[derive(JsonSchema)] /// struct MyStruct { /// foo: i32, /// } /// /// let my_schema = schema_for!(MyStruct); /// ``` /// /// When manually implementing `JsonSchema`, as well as determining an appropriate schema, /// you will need to determine an appropriate name and ID for the type. /// For non-generic types, the type name/path are suitable for this: /// ``` /// use schemars::{gen::SchemaGenerator, schema::Schema, JsonSchema}; /// use std::borrow::Cow; /// /// struct NonGenericType; /// /// impl JsonSchema for NonGenericType { /// fn schema_name() -> String { /// // Exclude the module path to make the name in generated schemas clearer. /// "NonGenericType".to_owned() /// } /// /// fn schema_id() -> Cow<'static, str> { /// // Include the module, in case a type with the same name is in another module/crate /// Cow::Borrowed(concat!(module_path!(), "::NonGenericType")) /// } /// /// fn json_schema(_gen: &mut SchemaGenerator) -> Schema { /// todo!() /// } /// } /// /// assert_eq!(NonGenericType::schema_id(), <&mut NonGenericType>::schema_id()); /// ``` /// /// But generic type parameters which may affect the generated schema should typically be included in the name/ID: /// ``` /// use schemars::{gen::SchemaGenerator, schema::Schema, JsonSchema}; /// use std::{borrow::Cow, marker::PhantomData}; /// /// struct GenericType(PhantomData); /// /// impl JsonSchema for GenericType { /// fn schema_name() -> String { /// format!("GenericType_{}", T::schema_name()) /// } /// /// fn schema_id() -> Cow<'static, str> { /// Cow::Owned(format!( /// "{}::GenericType<{}>", /// module_path!(), /// T::schema_id() /// )) /// } /// /// fn json_schema(_gen: &mut SchemaGenerator) -> Schema { /// todo!() /// } /// } /// /// assert_eq!(>::schema_id(), <&mut GenericType<&i32>>::schema_id()); /// ``` /// pub trait JsonSchema { /// Whether JSON Schemas generated for this type should be re-used where possible using the `$ref` keyword. /// /// For trivial types (such as primitives), this should return `false`. For more complex types, it should return `true`. /// For recursive types, this **must** return `true` to prevent infinite cycles when generating schemas. /// /// By default, this returns `true`. fn is_referenceable() -> bool { true } /// The name of the generated JSON Schema. /// /// This is used as the title for root schemas, and the key within the root's `definitions` property for subschemas. fn schema_name() -> String; /// Returns a string that uniquely identifies the schema produced by this type. /// /// This does not have to be a human-readable string, and the value will not itself be included in generated schemas. /// If two types produce different schemas, then they **must** have different `schema_id()`s, /// but two types that produce identical schemas should *ideally* have the same `schema_id()`. /// /// The default implementation returns the same value as `schema_name()`. fn schema_id() -> Cow<'static, str> { Cow::Owned(Self::schema_name()) } /// Generates a JSON Schema for this type. /// /// If the returned schema depends on any [referenceable](JsonSchema::is_referenceable) schemas, then this method will /// add them to the [`SchemaGenerator`](gen::SchemaGenerator)'s schema definitions. /// /// This should not return a `$ref` schema. fn json_schema(gen: &mut gen::SchemaGenerator) -> Schema; // TODO document and bring into public API? #[doc(hidden)] fn _schemars_private_non_optional_json_schema(gen: &mut gen::SchemaGenerator) -> Schema { Self::json_schema(gen) } // TODO document and bring into public API? #[doc(hidden)] fn _schemars_private_is_option() -> bool { false } } #[cfg(test)] pub mod tests { use super::*; pub fn schema_object_for() -> schema::SchemaObject { schema_object(schema_for::()) } pub fn schema_for() -> schema::Schema { let mut gen = gen::SchemaGenerator::default(); T::json_schema(&mut gen) } pub fn schema_object(schema: schema::Schema) -> schema::SchemaObject { match schema { schema::Schema::Object(o) => o, s => panic!("Schema was not an object: {:?}", s), } } } schemars-0.8.16/src/macros.rs000064400000000000000000000044460072674642500142060ustar 00000000000000/// Generates a [`RootSchema`](crate::schema::RootSchema) for the given type using default settings. /// /// The type must implement [`JsonSchema`](crate::JsonSchema). /// /// # Example /// ``` /// use schemars::{schema_for, JsonSchema}; /// /// #[derive(JsonSchema)] /// struct MyStruct { /// foo: i32, /// } /// /// let my_schema = schema_for!(MyStruct); /// ``` #[cfg(doc)] #[macro_export] macro_rules! schema_for { ($type:ty) => { $crate::gen::SchemaGenerator::default().into_root_schema_for::<$type>() }; } /// Generates a [`RootSchema`](crate::schema::RootSchema) for the given type using default settings. /// /// The type must implement [`JsonSchema`](crate::JsonSchema). /// /// # Example /// ``` /// use schemars::{schema_for, JsonSchema}; /// /// #[derive(JsonSchema)] /// struct MyStruct { /// foo: i32, /// } /// /// let my_schema = schema_for!(MyStruct); /// ``` #[cfg(not(doc))] #[macro_export] macro_rules! schema_for { ($type:ty) => { $crate::gen::SchemaGenerator::default().into_root_schema_for::<$type>() }; ($_:expr) => { compile_error!("This argument to `schema_for!` is not a type - did you mean to use `schema_for_value!` instead?") }; } /// Generates a [`RootSchema`](crate::schema::RootSchema) for the given example value using default settings. /// /// The value must implement [`Serialize`](serde::Serialize). If the value also implements [`JsonSchema`](crate::JsonSchema), /// then prefer using the [`schema_for!`](schema_for) macro which will generally produce a more precise schema, /// particularly when the value contains any enums. /// /// If the `Serialize` implementation of the value decides to fail, this macro will panic. /// For a non-panicking alternative, create a [`SchemaGenerator`](crate::gen::SchemaGenerator) and use /// its [`into_root_schema_for_value`](crate::gen::SchemaGenerator::into_root_schema_for_value) method. /// /// # Example /// ``` /// use schemars::schema_for_value; /// /// #[derive(serde::Serialize)] /// struct MyStruct { /// foo: i32, /// } /// /// let my_schema = schema_for_value!(MyStruct { foo: 123 }); /// ``` #[macro_export] macro_rules! schema_for_value { ($value:expr) => { $crate::gen::SchemaGenerator::default() .into_root_schema_for_value(&$value) .unwrap() }; } schemars-0.8.16/src/schema.rs000064400000000000000000000555650072674642500141720ustar 00000000000000/*! JSON Schema types. */ #[cfg(feature = "impl_json_schema")] use crate as schemars; #[cfg(feature = "impl_json_schema")] use crate::JsonSchema; use crate::{Map, Set}; use serde::{Deserialize, Serialize}; use serde_json::Value; use std::ops::Deref; /// A JSON Schema. #[allow(clippy::large_enum_variant)] #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] #[cfg_attr(feature = "impl_json_schema", derive(JsonSchema))] #[serde(untagged)] pub enum Schema { /// A trivial boolean JSON Schema. /// /// The schema `true` matches everything (always passes validation), whereas the schema `false` /// matches nothing (always fails validation). Bool(bool), /// A JSON Schema object. Object(SchemaObject), } impl Schema { /// Creates a new `$ref` schema. /// /// The given reference string should be a URI reference. This will usually be a JSON Pointer /// in [URI Fragment representation](https://tools.ietf.org/html/rfc6901#section-6). pub fn new_ref(reference: String) -> Self { SchemaObject::new_ref(reference).into() } /// Returns `true` if `self` is a `$ref` schema. /// /// If `self` is a [`SchemaObject`] with `Some` [`reference`](struct.SchemaObject.html#structfield.reference) set, this returns `true`. /// Otherwise, returns `false`. pub fn is_ref(&self) -> bool { match self { Schema::Object(o) => o.is_ref(), _ => false, } } /// Converts the given schema (if it is a boolean schema) into an equivalent schema object. /// /// If the given schema is already a schema object, this has no effect. /// /// # Example /// ``` /// use schemars::schema::{Schema, SchemaObject}; /// /// let bool_schema = Schema::Bool(true); /// /// assert_eq!(bool_schema.into_object(), SchemaObject::default()); /// ``` pub fn into_object(self) -> SchemaObject { match self { Schema::Object(o) => o, Schema::Bool(true) => SchemaObject::default(), Schema::Bool(false) => SchemaObject { subschemas: Some(Box::new(SubschemaValidation { not: Some(Schema::Object(Default::default()).into()), ..Default::default() })), ..Default::default() }, } } } impl From for Schema { fn from(o: SchemaObject) -> Self { Schema::Object(o) } } impl From for Schema { fn from(b: bool) -> Self { Schema::Bool(b) } } /// The root object of a JSON Schema document. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)] #[cfg_attr(feature = "impl_json_schema", derive(JsonSchema))] #[serde(rename_all = "camelCase", default)] pub struct RootSchema { /// The `$schema` keyword. /// /// See [JSON Schema 8.1.1. The "$schema" Keyword](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.1.1). #[serde(rename = "$schema", skip_serializing_if = "Option::is_none")] pub meta_schema: Option, /// The root schema itself. #[serde(flatten)] pub schema: SchemaObject, /// The `definitions` keyword. /// /// In JSON Schema draft 2019-09 this was replaced by $defs, but in Schemars this is still /// serialized as `definitions` for backward-compatibility. /// /// See [JSON Schema 8.2.5. Schema Re-Use With "$defs"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.5), /// and [JSON Schema (draft 07) 9. Schema Re-Use With "definitions"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-9). #[serde(alias = "$defs", skip_serializing_if = "Map::is_empty")] pub definitions: Map, } /// A JSON Schema object. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)] #[cfg_attr(feature = "impl_json_schema", derive(JsonSchema))] #[serde(rename_all = "camelCase", default)] pub struct SchemaObject { /// Properties which annotate the [`SchemaObject`] which typically have no effect when an object is being validated against the schema. #[serde(flatten, deserialize_with = "skip_if_default")] pub metadata: Option>, /// The `type` keyword. /// /// See [JSON Schema Validation 6.1.1. "type"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.1) /// and [JSON Schema 4.2.1. Instance Data Model](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-4.2.1). #[serde(rename = "type", skip_serializing_if = "Option::is_none")] pub instance_type: Option>, /// The `format` keyword. /// /// See [JSON Schema Validation 7. A Vocabulary for Semantic Content With "format"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-7). #[serde(skip_serializing_if = "Option::is_none")] pub format: Option, /// The `enum` keyword. /// /// See [JSON Schema Validation 6.1.2. "enum"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.2) #[serde(rename = "enum", skip_serializing_if = "Option::is_none")] pub enum_values: Option>, /// The `const` keyword. /// /// See [JSON Schema Validation 6.1.3. "const"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.3) #[serde( rename = "const", skip_serializing_if = "Option::is_none", deserialize_with = "allow_null" )] pub const_value: Option, /// Properties of the [`SchemaObject`] which define validation assertions in terms of other schemas. #[serde(flatten, deserialize_with = "skip_if_default")] pub subschemas: Option>, /// Properties of the [`SchemaObject`] which define validation assertions for numbers. #[serde(flatten, deserialize_with = "skip_if_default")] pub number: Option>, /// Properties of the [`SchemaObject`] which define validation assertions for strings. #[serde(flatten, deserialize_with = "skip_if_default")] pub string: Option>, /// Properties of the [`SchemaObject`] which define validation assertions for arrays. #[serde(flatten, deserialize_with = "skip_if_default")] pub array: Option>, /// Properties of the [`SchemaObject`] which define validation assertions for objects. #[serde(flatten, deserialize_with = "skip_if_default")] pub object: Option>, /// The `$ref` keyword. /// /// See [JSON Schema 8.2.4.1. Direct References with "$ref"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.4.1). #[serde(rename = "$ref", skip_serializing_if = "Option::is_none")] pub reference: Option, /// Arbitrary extra properties which are not part of the JSON Schema specification, or which `schemars` does not support. #[serde(flatten)] pub extensions: Map, } // Deserializing "null" to `Option` directly results in `None`, // this function instead makes it deserialize to `Some(Value::Null)`. fn allow_null<'de, D>(de: D) -> Result, D::Error> where D: serde::Deserializer<'de>, { Value::deserialize(de).map(Option::Some) } fn skip_if_default<'de, D, T>(deserializer: D) -> Result>, D::Error> where D: serde::Deserializer<'de>, T: Deserialize<'de> + Default + PartialEq, { let value = T::deserialize(deserializer)?; if value == T::default() { Ok(None) } else { Ok(Some(Box::new(value))) } } macro_rules! get_or_insert_default_fn { ($name:ident, $ret:ty) => { get_or_insert_default_fn!( concat!( "Returns a mutable reference to this schema's [`", stringify!($ret), "`](#structfield.", stringify!($name), "), creating it if it was `None`." ), $name, $ret ); }; ($doc:expr, $name:ident, $ret:ty) => { #[doc = $doc] pub fn $name(&mut self) -> &mut $ret { self.$name.get_or_insert_with(Default::default) } }; } impl SchemaObject { /// Creates a new `$ref` schema. /// /// The given reference string should be a URI reference. This will usually be a JSON Pointer /// in [URI Fragment representation](https://tools.ietf.org/html/rfc6901#section-6). pub fn new_ref(reference: String) -> Self { SchemaObject { reference: Some(reference), ..Default::default() } } /// Returns `true` if `self` is a `$ref` schema. /// /// If `self` has `Some` [`reference`](struct.SchemaObject.html#structfield.reference) set, this returns `true`. /// Otherwise, returns `false`. pub fn is_ref(&self) -> bool { self.reference.is_some() } /// Returns `true` if `self` accepts values of the given type, according to the [`instance_type`](struct.SchemaObject.html#structfield.instance_type) field. /// /// This is a basic check that always returns `true` if no `instance_type` is specified on the schema, /// and does not check any subschemas. Because of this, both `{}` and `{"not": {}}` accept any type according /// to this method. pub fn has_type(&self, ty: InstanceType) -> bool { self.instance_type .as_ref() .map_or(true, |x| x.contains(&ty)) } get_or_insert_default_fn!(metadata, Metadata); get_or_insert_default_fn!(subschemas, SubschemaValidation); get_or_insert_default_fn!(number, NumberValidation); get_or_insert_default_fn!(string, StringValidation); get_or_insert_default_fn!(array, ArrayValidation); get_or_insert_default_fn!(object, ObjectValidation); } impl From for SchemaObject { fn from(schema: Schema) -> Self { schema.into_object() } } /// Properties which annotate a [`SchemaObject`] which typically have no effect when an object is being validated against the schema. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)] #[cfg_attr(feature = "impl_json_schema", derive(JsonSchema))] #[serde(rename_all = "camelCase", default)] pub struct Metadata { /// The `$id` keyword. /// /// See [JSON Schema 8.2.2. The "$id" Keyword](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.2). #[serde(rename = "$id", skip_serializing_if = "Option::is_none")] pub id: Option, /// The `title` keyword. /// /// See [JSON Schema Validation 9.1. "title" and "description"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.1). #[serde(skip_serializing_if = "Option::is_none")] pub title: Option, /// The `description` keyword. /// /// See [JSON Schema Validation 9.1. "title" and "description"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.1). #[serde(skip_serializing_if = "Option::is_none")] pub description: Option, /// The `default` keyword. /// /// See [JSON Schema Validation 9.2. "default"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.2). #[serde( skip_serializing_if = "Option::is_none", deserialize_with = "allow_null" )] pub default: Option, /// The `deprecated` keyword. /// /// See [JSON Schema Validation 9.3. "deprecated"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.3). #[serde(skip_serializing_if = "is_false")] pub deprecated: bool, /// The `readOnly` keyword. /// /// See [JSON Schema Validation 9.4. "readOnly" and "writeOnly"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.4). #[serde(skip_serializing_if = "is_false")] pub read_only: bool, /// The `writeOnly` keyword. /// /// See [JSON Schema Validation 9.4. "readOnly" and "writeOnly"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.4). #[serde(skip_serializing_if = "is_false")] pub write_only: bool, /// The `examples` keyword. /// /// See [JSON Schema Validation 9.5. "examples"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.5). #[serde(skip_serializing_if = "Vec::is_empty")] pub examples: Vec, } #[allow(clippy::trivially_copy_pass_by_ref)] fn is_false(b: &bool) -> bool { !b } /// Properties of a [`SchemaObject`] which define validation assertions in terms of other schemas. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)] #[cfg_attr(feature = "impl_json_schema", derive(JsonSchema))] #[serde(rename_all = "camelCase", default)] pub struct SubschemaValidation { /// The `allOf` keyword. /// /// See [JSON Schema 9.2.1.1. "allOf"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.1). #[serde(skip_serializing_if = "Option::is_none")] pub all_of: Option>, /// The `anyOf` keyword. /// /// See [JSON Schema 9.2.1.2. "anyOf"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.2). #[serde(skip_serializing_if = "Option::is_none")] pub any_of: Option>, /// The `oneOf` keyword. /// /// See [JSON Schema 9.2.1.3. "oneOf"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.3). #[serde(skip_serializing_if = "Option::is_none")] pub one_of: Option>, /// The `not` keyword. /// /// See [JSON Schema 9.2.1.4. "not"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.4). #[serde(skip_serializing_if = "Option::is_none")] pub not: Option>, /// The `if` keyword. /// /// See [JSON Schema 9.2.2.1. "if"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.1). #[serde(rename = "if", skip_serializing_if = "Option::is_none")] pub if_schema: Option>, /// The `then` keyword. /// /// See [JSON Schema 9.2.2.2. "then"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.2). #[serde(rename = "then", skip_serializing_if = "Option::is_none")] pub then_schema: Option>, /// The `else` keyword. /// /// See [JSON Schema 9.2.2.3. "else"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.3). #[serde(rename = "else", skip_serializing_if = "Option::is_none")] pub else_schema: Option>, } /// Properties of a [`SchemaObject`] which define validation assertions for numbers. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)] #[cfg_attr(feature = "impl_json_schema", derive(JsonSchema))] #[serde(rename_all = "camelCase", default)] pub struct NumberValidation { /// The `multipleOf` keyword. /// /// See [JSON Schema Validation 6.2.1. "multipleOf"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.1). #[serde(skip_serializing_if = "Option::is_none")] pub multiple_of: Option, /// The `maximum` keyword. /// /// See [JSON Schema Validation 6.2.2. "maximum"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.2). #[serde(skip_serializing_if = "Option::is_none")] pub maximum: Option, /// The `exclusiveMaximum` keyword. /// /// See [JSON Schema Validation 6.2.3. "exclusiveMaximum"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.3). #[serde(skip_serializing_if = "Option::is_none")] pub exclusive_maximum: Option, /// The `minimum` keyword. /// /// See [JSON Schema Validation 6.2.4. "minimum"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.4). #[serde(skip_serializing_if = "Option::is_none")] pub minimum: Option, /// The `exclusiveMinimum` keyword. /// /// See [JSON Schema Validation 6.2.5. "exclusiveMinimum"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.5). #[serde(skip_serializing_if = "Option::is_none")] pub exclusive_minimum: Option, } /// Properties of a [`SchemaObject`] which define validation assertions for strings. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)] #[cfg_attr(feature = "impl_json_schema", derive(JsonSchema))] #[serde(rename_all = "camelCase", default)] pub struct StringValidation { /// The `maxLength` keyword. /// /// See [JSON Schema Validation 6.3.1. "maxLength"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.1). #[serde(skip_serializing_if = "Option::is_none")] pub max_length: Option, /// The `minLength` keyword. /// /// See [JSON Schema Validation 6.3.2. "minLength"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.2). #[serde(skip_serializing_if = "Option::is_none")] pub min_length: Option, /// The `pattern` keyword. /// /// See [JSON Schema Validation 6.3.3. "pattern"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.3). #[serde(skip_serializing_if = "Option::is_none")] pub pattern: Option, } /// Properties of a [`SchemaObject`] which define validation assertions for arrays. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)] #[cfg_attr(feature = "impl_json_schema", derive(JsonSchema))] #[serde(rename_all = "camelCase", default)] pub struct ArrayValidation { /// The `items` keyword. /// /// See [JSON Schema 9.3.1.1. "items"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.1). #[serde(skip_serializing_if = "Option::is_none")] pub items: Option>, /// The `additionalItems` keyword. /// /// See [JSON Schema 9.3.1.2. "additionalItems"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.2). #[serde(skip_serializing_if = "Option::is_none")] pub additional_items: Option>, /// The `maxItems` keyword. /// /// See [JSON Schema Validation 6.4.1. "maxItems"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.1). #[serde(skip_serializing_if = "Option::is_none")] pub max_items: Option, /// The `minItems` keyword. /// /// See [JSON Schema Validation 6.4.2. "minItems"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.2). #[serde(skip_serializing_if = "Option::is_none")] pub min_items: Option, /// The `uniqueItems` keyword. /// /// See [JSON Schema Validation 6.4.3. "uniqueItems"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.3). #[serde(skip_serializing_if = "Option::is_none")] pub unique_items: Option, /// The `contains` keyword. /// /// See [JSON Schema 9.3.1.4. "contains"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.4). #[serde(skip_serializing_if = "Option::is_none")] pub contains: Option>, } /// Properties of a [`SchemaObject`] which define validation assertions for objects. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)] #[cfg_attr(feature = "impl_json_schema", derive(JsonSchema))] #[serde(rename_all = "camelCase", default)] pub struct ObjectValidation { /// The `maxProperties` keyword. /// /// See [JSON Schema Validation 6.5.1. "maxProperties"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.1). #[serde(skip_serializing_if = "Option::is_none")] pub max_properties: Option, /// The `minProperties` keyword. /// /// See [JSON Schema Validation 6.5.2. "minProperties"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.2). #[serde(skip_serializing_if = "Option::is_none")] pub min_properties: Option, /// The `required` keyword. /// /// See [JSON Schema Validation 6.5.3. "required"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.3). #[serde(skip_serializing_if = "Set::is_empty")] pub required: Set, /// The `properties` keyword. /// /// See [JSON Schema 9.3.2.1. "properties"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.1). #[serde(skip_serializing_if = "Map::is_empty")] pub properties: Map, /// The `patternProperties` keyword. /// /// See [JSON Schema 9.3.2.2. "patternProperties"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.2). #[serde(skip_serializing_if = "Map::is_empty")] pub pattern_properties: Map, /// The `additionalProperties` keyword. /// /// See [JSON Schema 9.3.2.3. "additionalProperties"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.3). #[serde(skip_serializing_if = "Option::is_none")] pub additional_properties: Option>, /// The `propertyNames` keyword. /// /// See [JSON Schema 9.3.2.5. "propertyNames"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.5). #[serde(skip_serializing_if = "Option::is_none")] pub property_names: Option>, } /// The possible types of values in JSON Schema documents. /// /// See [JSON Schema 4.2.1. Instance Data Model](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-4.2.1). #[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "impl_json_schema", derive(JsonSchema))] #[serde(rename_all = "camelCase")] pub enum InstanceType { Null, Boolean, Object, Array, Number, String, Integer, } /// A type which can be serialized as a single item, or multiple items. /// /// In some contexts, a `Single` may be semantically distinct from a `Vec` containing only item. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "impl_json_schema", derive(JsonSchema))] #[serde(untagged)] pub enum SingleOrVec { Single(Box), Vec(Vec), } impl From for SingleOrVec { fn from(single: T) -> Self { SingleOrVec::Single(Box::new(single)) } } impl From> for SingleOrVec { fn from(vec: Vec) -> Self { SingleOrVec::Vec(vec) } } impl SingleOrVec { /// Returns `true` if `self` is either a `Single` equal to `x`, or a `Vec` containing `x`. /// /// # Examples /// /// ``` /// use schemars::schema::SingleOrVec; /// /// let s = SingleOrVec::from(10); /// assert!(s.contains(&10)); /// assert!(!s.contains(&20)); /// /// let v = SingleOrVec::from(vec![10, 20]); /// assert!(v.contains(&10)); /// assert!(v.contains(&20)); /// assert!(!v.contains(&30)); /// ``` pub fn contains(&self, x: &T) -> bool { match self { SingleOrVec::Single(s) => s.deref() == x, SingleOrVec::Vec(v) => v.contains(x), } } } schemars-0.8.16/src/ser.rs000064400000000000000000000342320072674642500135070ustar 00000000000000use crate::schema::*; use crate::JsonSchema; use crate::{gen::SchemaGenerator, Map}; use serde_json::{Error, Value}; use std::{convert::TryInto, fmt::Display}; pub(crate) struct Serializer<'a> { pub(crate) gen: &'a mut SchemaGenerator, pub(crate) include_title: bool, } pub(crate) struct SerializeSeq<'a> { gen: &'a mut SchemaGenerator, items: Option, } pub(crate) struct SerializeTuple<'a> { gen: &'a mut SchemaGenerator, items: Vec, title: &'static str, } pub(crate) struct SerializeMap<'a> { gen: &'a mut SchemaGenerator, properties: Map, current_key: Option, title: &'static str, } macro_rules! forward_to_subschema_for { ($fn:ident, $ty:ty) => { fn $fn(self, _value: $ty) -> Result { Ok(self.gen.subschema_for::<$ty>()) } }; } macro_rules! return_instance_type { ($fn:ident, $ty:ty, $instance_type:ident) => { fn $fn(self, _value: $ty) -> Result { Ok(SchemaObject { instance_type: Some(InstanceType::$instance_type.into()), ..Default::default() } .into()) } }; } impl<'a> serde::Serializer for Serializer<'a> { type Ok = Schema; type Error = Error; type SerializeSeq = SerializeSeq<'a>; type SerializeTuple = SerializeTuple<'a>; type SerializeTupleStruct = SerializeTuple<'a>; type SerializeTupleVariant = Self; type SerializeMap = SerializeMap<'a>; type SerializeStruct = SerializeMap<'a>; type SerializeStructVariant = Self; return_instance_type!(serialize_i8, i8, Integer); return_instance_type!(serialize_i16, i16, Integer); return_instance_type!(serialize_i32, i32, Integer); return_instance_type!(serialize_i64, i64, Integer); return_instance_type!(serialize_i128, i128, Integer); return_instance_type!(serialize_u8, u8, Integer); return_instance_type!(serialize_u16, u16, Integer); return_instance_type!(serialize_u32, u32, Integer); return_instance_type!(serialize_u64, u64, Integer); return_instance_type!(serialize_u128, u128, Integer); return_instance_type!(serialize_f32, f32, Number); return_instance_type!(serialize_f64, f64, Number); forward_to_subschema_for!(serialize_bool, bool); forward_to_subschema_for!(serialize_char, char); forward_to_subschema_for!(serialize_str, &str); forward_to_subschema_for!(serialize_bytes, &[u8]); fn collect_str(self, _value: &T) -> Result where T: Display, { Ok(self.gen.subschema_for::<&str>()) } fn collect_map(self, iter: I) -> Result where K: serde::Serialize, V: serde::Serialize, I: IntoIterator, { let value_schema = iter .into_iter() .try_fold(None, |acc, (_, v)| { if acc == Some(Schema::Bool(true)) { return Ok(acc); } let schema = v.serialize(Serializer { gen: self.gen, include_title: false, })?; Ok(match &acc { None => Some(schema), Some(items) if items != &schema => Some(Schema::Bool(true)), _ => acc, }) })? .unwrap_or(Schema::Bool(true)); Ok(SchemaObject { instance_type: Some(InstanceType::Object.into()), object: Some(Box::new(ObjectValidation { additional_properties: Some(Box::new(value_schema)), ..ObjectValidation::default() })), ..SchemaObject::default() } .into()) } fn serialize_none(self) -> Result { Ok(self.gen.subschema_for::>()) } fn serialize_unit(self) -> Result { self.serialize_none() } fn serialize_some(self, value: &T) -> Result where T: serde::Serialize, { // FIXME nasty duplication of `impl JsonSchema for Option` fn add_null_type(instance_type: &mut SingleOrVec) { match instance_type { SingleOrVec::Single(ty) if **ty != InstanceType::Null => { *instance_type = vec![**ty, InstanceType::Null].into() } SingleOrVec::Vec(ty) if !ty.contains(&InstanceType::Null) => { ty.push(InstanceType::Null) } _ => {} }; } let mut schema = value.serialize(Serializer { gen: self.gen, include_title: false, })?; if self.gen.settings().option_add_null_type { schema = match schema { Schema::Bool(true) => Schema::Bool(true), Schema::Bool(false) => <()>::json_schema(self.gen), Schema::Object(SchemaObject { instance_type: Some(ref mut instance_type), .. }) => { add_null_type(instance_type); schema } schema => SchemaObject { subschemas: Some(Box::new(SubschemaValidation { any_of: Some(vec![schema, <()>::json_schema(self.gen)]), ..Default::default() })), ..Default::default() } .into(), } } if self.gen.settings().option_nullable { let mut schema_obj = schema.into_object(); schema_obj .extensions .insert("nullable".to_owned(), serde_json::json!(true)); schema = Schema::Object(schema_obj); }; Ok(schema) } fn serialize_unit_struct(self, _name: &'static str) -> Result { Ok(self.gen.subschema_for::<()>()) } fn serialize_unit_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, ) -> Result { Ok(Schema::Bool(true)) } fn serialize_newtype_struct( self, name: &'static str, value: &T, ) -> Result where T: serde::Serialize, { let include_title = self.include_title; let mut result = value.serialize(self); if include_title { if let Ok(Schema::Object(ref mut object)) = result { object.metadata().title = Some(name.to_string()); } } result } fn serialize_newtype_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, _value: &T, ) -> Result where T: serde::Serialize, { Ok(Schema::Bool(true)) } fn serialize_seq(self, _len: Option) -> Result { Ok(SerializeSeq { gen: self.gen, items: None, }) } fn serialize_tuple(self, len: usize) -> Result { Ok(SerializeTuple { gen: self.gen, items: Vec::with_capacity(len), title: "", }) } fn serialize_tuple_struct( self, name: &'static str, len: usize, ) -> Result { let title = if self.include_title { name } else { "" }; Ok(SerializeTuple { gen: self.gen, items: Vec::with_capacity(len), title, }) } fn serialize_tuple_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize, ) -> Result { Ok(self) } fn serialize_map(self, _len: Option) -> Result { Ok(SerializeMap { gen: self.gen, properties: Map::new(), current_key: None, title: "", }) } fn serialize_struct( self, name: &'static str, _len: usize, ) -> Result { let title = if self.include_title { name } else { "" }; Ok(SerializeMap { gen: self.gen, properties: Map::new(), current_key: None, title, }) } fn serialize_struct_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize, ) -> Result { Ok(self) } } impl serde::ser::SerializeTupleVariant for Serializer<'_> { type Ok = Schema; type Error = Error; fn serialize_field(&mut self, _value: &T) -> Result<(), Self::Error> where T: serde::Serialize, { Ok(()) } fn end(self) -> Result { Ok(Schema::Bool(true)) } } impl serde::ser::SerializeStructVariant for Serializer<'_> { type Ok = Schema; type Error = Error; fn serialize_field( &mut self, _key: &'static str, _value: &T, ) -> Result<(), Self::Error> where T: serde::Serialize, { Ok(()) } fn end(self) -> Result { Ok(Schema::Bool(true)) } } impl serde::ser::SerializeSeq for SerializeSeq<'_> { type Ok = Schema; type Error = Error; fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> where T: serde::Serialize, { if self.items != Some(Schema::Bool(true)) { let schema = value.serialize(Serializer { gen: self.gen, include_title: false, })?; match &self.items { None => self.items = Some(schema), Some(items) => { if items != &schema { self.items = Some(Schema::Bool(true)) } } } } Ok(()) } fn end(self) -> Result { let items = self.items.unwrap_or(Schema::Bool(true)); Ok(SchemaObject { instance_type: Some(InstanceType::Array.into()), array: Some(Box::new(ArrayValidation { items: Some(items.into()), ..ArrayValidation::default() })), ..SchemaObject::default() } .into()) } } impl serde::ser::SerializeTuple for SerializeTuple<'_> { type Ok = Schema; type Error = Error; fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> where T: serde::Serialize, { let schema = value.serialize(Serializer { gen: self.gen, include_title: false, })?; self.items.push(schema); Ok(()) } fn end(self) -> Result { let len = self.items.len().try_into().ok(); let mut schema = SchemaObject { instance_type: Some(InstanceType::Array.into()), array: Some(Box::new(ArrayValidation { items: Some(SingleOrVec::Vec(self.items)), max_items: len, min_items: len, ..ArrayValidation::default() })), ..SchemaObject::default() }; if !self.title.is_empty() { schema.metadata().title = Some(self.title.to_owned()); } Ok(schema.into()) } } impl serde::ser::SerializeTupleStruct for SerializeTuple<'_> { type Ok = Schema; type Error = Error; fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> where T: serde::Serialize, { serde::ser::SerializeTuple::serialize_element(self, value) } fn end(self) -> Result { serde::ser::SerializeTuple::end(self) } } impl serde::ser::SerializeMap for SerializeMap<'_> { type Ok = Schema; type Error = Error; fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> where T: serde::Serialize, { // FIXME this is too lenient - we should return an error if serde_json // doesn't allow T to be a key of a map. let json = serde_json::to_string(key)?; self.current_key = Some( json.trim_start_matches('"') .trim_end_matches('"') .to_string(), ); Ok(()) } fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> where T: serde::Serialize, { let key = self.current_key.take().unwrap_or_default(); let schema = value.serialize(Serializer { gen: self.gen, include_title: false, })?; self.properties.insert(key, schema); Ok(()) } fn end(self) -> Result { let mut schema = SchemaObject { instance_type: Some(InstanceType::Object.into()), object: Some(Box::new(ObjectValidation { properties: self.properties, ..ObjectValidation::default() })), ..SchemaObject::default() }; if !self.title.is_empty() { schema.metadata().title = Some(self.title.to_owned()); } Ok(schema.into()) } } impl serde::ser::SerializeStruct for SerializeMap<'_> { type Ok = Schema; type Error = Error; fn serialize_field( &mut self, key: &'static str, value: &T, ) -> Result<(), Self::Error> where T: serde::Serialize, { let prop_schema = value.serialize(Serializer { gen: self.gen, include_title: false, })?; self.properties.insert(key.to_string(), prop_schema); Ok(()) } fn end(self) -> Result { serde::ser::SerializeMap::end(self) } } schemars-0.8.16/src/visit.rs000064400000000000000000000167360072674642500140650ustar 00000000000000/*! Contains the [`Visitor`] trait, used to recursively modify a constructed schema and its subschemas. Sometimes you may want to apply a change to a schema, as well as all schemas contained within it. The easiest way to achieve this is by defining a type that implements [`Visitor`]. All methods of `Visitor` have a default implementation that makes no change but recursively visits all subschemas. When overriding one of these methods, you will *usually* want to still call this default implementation. # Example To add a custom property to all schemas: ``` use schemars::schema::SchemaObject; use schemars::visit::{Visitor, visit_schema_object}; pub struct MyVisitor; impl Visitor for MyVisitor { fn visit_schema_object(&mut self, schema: &mut SchemaObject) { // First, make our change to this schema schema.extensions.insert("my_property".to_string(), serde_json::json!("hello world")); // Then delegate to default implementation to visit any subschemas visit_schema_object(self, schema); } } ``` */ use crate::schema::{RootSchema, Schema, SchemaObject, SingleOrVec}; /// Trait used to recursively modify a constructed schema and its subschemas. pub trait Visitor { /// Override this method to modify a [`RootSchema`] and (optionally) its subschemas. /// /// When overriding this method, you will usually want to call the [`visit_root_schema`] function to visit subschemas. fn visit_root_schema(&mut self, root: &mut RootSchema) { visit_root_schema(self, root) } /// Override this method to modify a [`Schema`] and (optionally) its subschemas. /// /// When overriding this method, you will usually want to call the [`visit_schema`] function to visit subschemas. fn visit_schema(&mut self, schema: &mut Schema) { visit_schema(self, schema) } /// Override this method to modify a [`SchemaObject`] and (optionally) its subschemas. /// /// When overriding this method, you will usually want to call the [`visit_schema_object`] function to visit subschemas. fn visit_schema_object(&mut self, schema: &mut SchemaObject) { visit_schema_object(self, schema) } } /// Visits all subschemas of the [`RootSchema`]. pub fn visit_root_schema(v: &mut V, root: &mut RootSchema) { v.visit_schema_object(&mut root.schema); visit_map_values(v, &mut root.definitions); } /// Visits all subschemas of the [`Schema`]. pub fn visit_schema(v: &mut V, schema: &mut Schema) { if let Schema::Object(schema) = schema { v.visit_schema_object(schema) } } /// Visits all subschemas of the [`SchemaObject`]. pub fn visit_schema_object(v: &mut V, schema: &mut SchemaObject) { if let Some(sub) = &mut schema.subschemas { visit_vec(v, &mut sub.all_of); visit_vec(v, &mut sub.any_of); visit_vec(v, &mut sub.one_of); visit_box(v, &mut sub.not); visit_box(v, &mut sub.if_schema); visit_box(v, &mut sub.then_schema); visit_box(v, &mut sub.else_schema); } if let Some(arr) = &mut schema.array { visit_single_or_vec(v, &mut arr.items); visit_box(v, &mut arr.additional_items); visit_box(v, &mut arr.contains); } if let Some(obj) = &mut schema.object { visit_map_values(v, &mut obj.properties); visit_map_values(v, &mut obj.pattern_properties); visit_box(v, &mut obj.additional_properties); visit_box(v, &mut obj.property_names); } } fn visit_box(v: &mut V, target: &mut Option>) { if let Some(s) = target { v.visit_schema(s) } } fn visit_vec(v: &mut V, target: &mut Option>) { if let Some(vec) = target { for s in vec { v.visit_schema(s) } } } fn visit_map_values(v: &mut V, target: &mut crate::Map) { for s in target.values_mut() { v.visit_schema(s) } } fn visit_single_or_vec(v: &mut V, target: &mut Option>) { match target { None => {} Some(SingleOrVec::Single(s)) => v.visit_schema(s), Some(SingleOrVec::Vec(vec)) => { for s in vec { v.visit_schema(s) } } } } /// This visitor will replace all boolean JSON Schemas with equivalent object schemas. /// /// This is useful for dialects of JSON Schema (e.g. OpenAPI 3.0) that do not support booleans as schemas. #[derive(Debug, Clone)] pub struct ReplaceBoolSchemas { /// When set to `true`, a schema's `additionalProperties` property will not be changed from a boolean. pub skip_additional_properties: bool, } impl Visitor for ReplaceBoolSchemas { fn visit_schema(&mut self, schema: &mut Schema) { visit_schema(self, schema); if let Schema::Bool(b) = *schema { *schema = Schema::Bool(b).into_object().into() } } fn visit_schema_object(&mut self, schema: &mut SchemaObject) { if self.skip_additional_properties { if let Some(obj) = &mut schema.object { if let Some(ap) = &obj.additional_properties { if let Schema::Bool(_) = ap.as_ref() { let additional_properties = obj.additional_properties.take(); visit_schema_object(self, schema); schema.object().additional_properties = additional_properties; return; } } } } visit_schema_object(self, schema); } } /// This visitor will restructure JSON Schema objects so that the `$ref` property will never appear alongside any other properties. /// /// This is useful for dialects of JSON Schema (e.g. Draft 7) that do not support other properties alongside `$ref`. #[derive(Debug, Clone)] pub struct RemoveRefSiblings; impl Visitor for RemoveRefSiblings { fn visit_schema_object(&mut self, schema: &mut SchemaObject) { visit_schema_object(self, schema); if let Some(reference) = schema.reference.take() { if schema == &SchemaObject::default() { schema.reference = Some(reference); } else { let ref_schema = Schema::new_ref(reference); let all_of = &mut schema.subschemas().all_of; match all_of { Some(vec) => vec.push(ref_schema), None => *all_of = Some(vec![ref_schema]), } } } } } /// This visitor will remove the `examples` schema property and (if present) set its first value as the `example` property. /// /// This is useful for dialects of JSON Schema (e.g. OpenAPI 3.0) that do not support the `examples` property. #[derive(Debug, Clone)] pub struct SetSingleExample { /// When set to `true`, the `examples` property will not be removed, but its first value will still be copied to `example`. pub retain_examples: bool, } impl Visitor for SetSingleExample { fn visit_schema_object(&mut self, schema: &mut SchemaObject) { visit_schema_object(self, schema); let first_example = schema.metadata.as_mut().and_then(|m| { if self.retain_examples { m.examples.first().cloned() } else { m.examples.drain(..).next() } }); if let Some(example) = first_example { schema.extensions.insert("example".to_owned(), example); } } } schemars-0.8.16/tests/actual/README.md000064400000000000000000000002600072674642500154450ustar 00000000000000# Actual Generated Schemas If a test fails because a generated schema did not match the expected JSON, then the actual schema will be written to a JSON file in this directory.schemars-0.8.16/tests/arrayvec.rs000064400000000000000000000010370072674642500151020ustar 00000000000000mod util; use util::*; #[test] fn arrayvec05() -> TestResult { test_default_generated_schema::>("arrayvec") } #[test] 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") } schemars-0.8.16/tests/bound.rs000064400000000000000000000012240072674642500143730ustar 00000000000000mod util; use std::marker::PhantomData; use schemars::JsonSchema; use util::*; struct MyIterator; impl Iterator for MyIterator { type Item = String; fn next(&mut self) -> Option { unimplemented!() } } // The default trait bounds would require T to implement JsonSchema, // which MyIterator does not. #[derive(JsonSchema)] #[schemars(bound = "T::Item: JsonSchema", rename = "MyContainer")] pub struct MyContainer where T: Iterator, { pub associated: T::Item, pub generic: PhantomData, } #[test] fn manual_bound_set() -> TestResult { test_default_generated_schema::>("bound") } schemars-0.8.16/tests/bytes.rs000064400000000000000000000002330072674642500144110ustar 00000000000000mod util; use bytes::{Bytes, BytesMut}; use util::*; #[test] fn bytes() -> TestResult { test_default_generated_schema::<(Bytes, BytesMut)>("bytes") } schemars-0.8.16/tests/chrono.rs000064400000000000000000000006070072674642500145600ustar 00000000000000mod util; use chrono::prelude::*; use schemars::JsonSchema; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] struct ChronoTypes { weekday: Weekday, date_time: DateTime, naive_date: NaiveDate, naive_date_time: NaiveDateTime, naive_time: NaiveTime, } #[test] fn chrono_types() -> TestResult { test_default_generated_schema::("chrono-types") } schemars-0.8.16/tests/crate_alias.rs000064400000000000000000000005710072674642500155370ustar 00000000000000mod util; use ::schemars as not_schemars; use util::*; #[allow(unused_imports)] use std as schemars; #[allow(dead_code)] #[derive(not_schemars::JsonSchema)] #[schemars(crate = "not_schemars")] struct Struct { /// This is a document foo: i32, bar: bool, } #[test] fn test_crate_alias() -> TestResult { test_default_generated_schema::("crate_alias") } schemars-0.8.16/tests/decimal.rs000064400000000000000000000006050072674642500146640ustar 00000000000000mod util; use util::*; #[test] fn rust_decimal() -> TestResult { test_default_generated_schema::("rust_decimal") } #[test] fn bigdecimal03() -> TestResult { test_default_generated_schema::("bigdecimal03") } #[test] fn bigdecimal04() -> TestResult { test_default_generated_schema::("bigdecimal04") } schemars-0.8.16/tests/default.rs000064400000000000000000000022510072674642500147110ustar 00000000000000mod util; use schemars::JsonSchema; use util::*; fn is_default(value: &T) -> bool { value == &T::default() } fn ten_and_true() -> MyStruct2 { MyStruct2 { my_int: 10, my_bool: true, } } fn six() -> i32 { 6 } fn custom_serialize(value: &MyStruct2, ser: S) -> Result where S: serde::Serializer, { ser.collect_str(&format_args!("i:{} b:{}", value.my_int, value.my_bool)) } #[allow(dead_code)] #[derive(Default, JsonSchema)] #[serde(default)] struct MyStruct { my_int: i32, my_bool: bool, #[serde(serialize_with = "custom_serialize")] my_struct2: MyStruct2, #[serde( serialize_with = "custom_serialize", skip_serializing_if = "is_default" )] my_struct2_default_skipped: MyStruct2, not_serialize: NotSerialize, } #[allow(dead_code)] #[derive(Default, JsonSchema, PartialEq)] #[serde(default = "ten_and_true")] struct MyStruct2 { #[serde(default = "six")] my_int: i32, my_bool: bool, } #[derive(Default, JsonSchema)] struct NotSerialize; #[test] fn schema_default_values() -> TestResult { test_default_generated_schema::("default") } schemars-0.8.16/tests/deprecated.rs000064400000000000000000000013240072674642500153650ustar 00000000000000#![allow(deprecated)] mod util; use schemars::JsonSchema; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] #[deprecated] struct DeprecatedStruct { foo: i32, #[deprecated] deprecated_field: bool, } #[test] fn deprecated_struct() -> TestResult { test_default_generated_schema::("deprecated-struct") } #[allow(dead_code)] #[derive(JsonSchema)] #[deprecated] enum DeprecatedEnum { Unit, #[deprecated] DeprecatedUnitVariant, #[deprecated] DeprecatedStructVariant { foo: i32, #[deprecated] deprecated_field: bool, }, } #[test] fn deprecated_enum() -> TestResult { test_default_generated_schema::("deprecated-enum") } schemars-0.8.16/tests/dereference.rs000064400000000000000000000011500072674642500155310ustar 00000000000000use 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::(); let struct_schema = gen.definitions().get(&::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)); } schemars-0.8.16/tests/docs.rs000064400000000000000000000040130072674642500142130ustar 00000000000000mod util; use schemars::{gen::SchemaSettings, JsonSchema}; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] /** * * # This is the struct's title * * This is the struct's description. * */ struct MyStruct { /// # An integer my_int: i32, my_undocumented_bool: bool, /// A unit struct instance my_unit: MyUnitStruct, } /// # A Unit /// #[derive(JsonSchema)] struct MyUnitStruct; #[allow(dead_code)] #[doc = " # This is the enum's title "] #[doc = " This is "] #[derive(JsonSchema)] #[doc = " the enum's description."] enum MyEnum { UndocumentedUnit, UndocumentedUnit2, /// This comment is included in the generated schema :) DocumentedUnit, /// ## Complex variant /// This is a struct-like variant. Complex { /// ### A nullable string /// /// This field is a nullable string. /// /// This ///is /// the second /// line! /// /// /// /// /// And this is the third! my_nullable_string: Option, }, } #[test] fn doc_comments_struct() -> TestResult { test_default_generated_schema::("doc_comments_struct") } #[test] fn doc_comments_struct_ref_siblings() -> TestResult { let settings = SchemaSettings::draft2019_09(); test_generated_schema::("doc_comments_struct_ref_siblings", settings) } #[test] fn doc_comments_enum() -> TestResult { test_default_generated_schema::("doc_comments_enum") } /// # OverrideDocs struct /// This description should be overridden #[allow(dead_code)] #[derive(JsonSchema)] #[schemars(description = "New description")] struct OverrideDocs { /// # Overridden #[schemars(title = "My integer", description = "This is an i32")] my_int: i32, /// # Overridden /// Also overridden #[schemars(title = "", description = "")] my_undocumented_bool: bool, } #[test] fn doc_comments_override() -> TestResult { test_default_generated_schema::("doc_comments_override") } schemars-0.8.16/tests/either.rs000064400000000000000000000002370072674642500145470ustar 00000000000000mod util; use either::Either; use util::*; #[test] fn either() -> TestResult { test_default_generated_schema::>>("either") } schemars-0.8.16/tests/enum.rs000064400000000000000000000052000072674642500142260ustar 00000000000000mod util; use schemars::{JsonSchema, Map}; use util::*; // Ensure that schemars_derive uses the full path to std::string::String pub struct String; #[derive(JsonSchema)] struct UnitStruct; #[allow(dead_code)] #[derive(JsonSchema)] struct Struct { foo: i32, bar: bool, } #[allow(dead_code)] #[derive(JsonSchema)] #[schemars(rename_all = "camelCase")] enum External { UnitOne, StringMap(Map<&'static str, &'static str>), UnitStructNewType(UnitStruct), StructNewType(Struct), Struct { foo: i32, bar: bool, }, UnitTwo, Tuple(i32, bool), #[schemars(with = "i32")] WithInt, } #[test] fn enum_external_tag() -> TestResult { test_default_generated_schema::("enum-external") } #[allow(dead_code)] #[derive(JsonSchema)] #[schemars(tag = "typeProperty")] enum Internal { UnitOne, StringMap(Map<&'static str, &'static str>), UnitStructNewType(UnitStruct), StructNewType(Struct), Struct { foo: i32, bar: bool, }, UnitTwo, #[schemars(with = "i32")] WithInt, } #[test] fn enum_internal_tag() -> TestResult { test_default_generated_schema::("enum-internal") } #[allow(dead_code)] #[derive(JsonSchema)] #[schemars(untagged)] enum Untagged { UnitOne, StringMap(Map<&'static str, &'static str>), UnitStructNewType(UnitStruct), StructNewType(Struct), Struct { foo: i32, bar: bool, }, Tuple(i32, bool), #[schemars(with = "i32")] WithInt, } #[test] fn enum_untagged() -> TestResult { test_default_generated_schema::("enum-untagged") } #[allow(dead_code)] #[derive(JsonSchema)] #[schemars(tag = "t", content = "c")] enum Adjacent { UnitOne, StringMap(Map<&'static str, &'static str>), UnitStructNewType(UnitStruct), StructNewType(Struct), Struct { foo: i32, bar: bool, }, Tuple(i32, bool), UnitTwo, #[schemars(with = "i32")] WithInt, } #[test] fn enum_adjacent_tagged() -> TestResult { test_default_generated_schema::("enum-adjacent-tagged") } #[allow(dead_code)] #[derive(JsonSchema)] #[schemars(tag = "typeProperty")] enum SimpleInternal { A, B, C, } #[test] fn enum_simple_internal_tag() -> TestResult { test_default_generated_schema::("enum-simple-internal") } #[allow(dead_code)] #[derive(JsonSchema)] enum SoundOfMusic { /// # A deer /// /// A female deer Do, /// A drop of golden sun Re, /// A name I call myself Mi, } #[test] fn enum_unit_with_doc_comments() -> TestResult { test_default_generated_schema::("enum-unit-doc") } schemars-0.8.16/tests/enum_deny_unknown_fields.rs000064400000000000000000000054140072674642500203610ustar 00000000000000mod util; use schemars::{JsonSchema, Map}; use util::*; // Ensure that schemars_derive uses the full path to std::string::String pub struct String; #[derive(JsonSchema)] struct UnitStruct; #[allow(dead_code)] #[derive(JsonSchema)] struct Struct { foo: i32, bar: bool, } // Outer container should always have additionalProperties: false // `Struct` variant should have additionalProperties: false #[allow(dead_code)] #[derive(JsonSchema)] #[schemars(rename_all = "camelCase", deny_unknown_fields)] enum External { UnitOne, StringMap(Map<&'static str, &'static str>), UnitStructNewType(UnitStruct), StructNewType(Struct), Struct { foo: i32, bar: bool, }, UnitTwo, Tuple(i32, bool), #[schemars(with = "i32")] WithInt, } #[test] fn enum_external_tag() -> TestResult { test_default_generated_schema::("enum-external-duf") } // Only `Struct` variant should have additionalProperties: false #[allow(dead_code)] #[derive(JsonSchema)] #[schemars(tag = "typeProperty", deny_unknown_fields)] enum Internal { UnitOne, StringMap(Map<&'static str, &'static str>), UnitStructNewType(UnitStruct), StructNewType(Struct), Struct { foo: i32, bar: bool, }, UnitTwo, #[schemars(with = "i32")] WithInt, } #[test] fn enum_internal_tag() -> TestResult { test_default_generated_schema::("enum-internal-duf") } // Only `Struct` variant should have additionalProperties: false #[allow(dead_code)] #[derive(JsonSchema)] #[schemars(untagged, deny_unknown_fields)] enum Untagged { UnitOne, StringMap(Map<&'static str, &'static str>), UnitStructNewType(UnitStruct), StructNewType(Struct), Struct { foo: i32, bar: bool, }, Tuple(i32, bool), #[schemars(with = "i32")] WithInt, } #[test] fn enum_untagged() -> TestResult { test_default_generated_schema::("enum-untagged-duf") } // Outer container and `Struct` variant should have additionalProperties: false #[allow(dead_code)] #[derive(JsonSchema)] #[schemars(tag = "t", content = "c", deny_unknown_fields)] enum Adjacent { UnitOne, StringMap(Map<&'static str, &'static str>), UnitStructNewType(UnitStruct), StructNewType(Struct), Struct { foo: i32, bar: bool, }, Tuple(i32, bool), UnitTwo, #[schemars(with = "i32")] WithInt, } #[test] fn enum_adjacent_tagged() -> TestResult { test_default_generated_schema::("enum-adjacent-tagged-duf") } #[allow(dead_code)] #[derive(JsonSchema)] #[schemars(tag = "typeProperty", deny_unknown_fields)] enum SimpleInternal { A, B, C, } #[test] fn enum_simple_internal_tag() -> TestResult { test_default_generated_schema::("enum-simple-internal-duf") } schemars-0.8.16/tests/enum_repr.rs000064400000000000000000000011010072674642500152520ustar 00000000000000mod util; use schemars::JsonSchema_repr; use util::*; #[derive(JsonSchema_repr)] #[repr(u8)] pub enum Enum { Zero, One, Five = 5, Six, Three = 3, } #[test] fn enum_repr() -> TestResult { test_default_generated_schema::("enum-repr") } #[derive(JsonSchema_repr)] #[repr(i64)] #[serde(rename = "Renamed")] /// Description from comment pub enum EnumWithAttrs { Zero, One, Five = 5, Six, Three = 3, } #[test] fn enum_repr_with_attrs() -> TestResult { test_default_generated_schema::("enum-repr-with-attrs") } schemars-0.8.16/tests/enumset.rs000064400000000000000000000003760072674642500147530ustar 00000000000000mod util; use enumset::{EnumSet, EnumSetType}; use schemars::JsonSchema; use util::*; #[derive(EnumSetType, JsonSchema)] enum Foo { Bar, Baz, } #[test] fn enumset() -> TestResult { test_default_generated_schema::>("enumset") } schemars-0.8.16/tests/examples.rs000064400000000000000000000007360072674642500151110ustar 00000000000000mod util; use schemars::JsonSchema; use serde::Serialize; use util::*; #[derive(Default, JsonSchema, Serialize)] #[schemars(example = "Struct::default", example = "null")] struct Struct { #[schemars(example = "eight", example = "null")] foo: i32, bar: bool, #[schemars(example = "null")] baz: Option<&'static str>, } fn eight() -> i32 { 8 } fn null() {} #[test] fn examples() -> TestResult { test_default_generated_schema::("examples") } schemars-0.8.16/tests/expected/arrayvec.json000064400000000000000000000003110072674642500172220ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Array_up_to_size_16_of_int32", "type": "array", "items": { "type": "integer", "format": "int32" }, "maxItems": 16 }schemars-0.8.16/tests/expected/arrayvec_string.json000064400000000000000000000001430072674642500206130ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "String", "type": "string" }schemars-0.8.16/tests/expected/bigdecimal03.json000064400000000000000000000002130072674642500176320ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Decimal", "type": "string", "pattern": "^-?[0-9]+(\\.[0-9]+)?$" }schemars-0.8.16/tests/expected/bigdecimal04.json000064400000000000000000000002130072674642500176330ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Decimal", "type": "string", "pattern": "^-?[0-9]+(\\.[0-9]+)?$" }schemars-0.8.16/tests/expected/bound.json000064400000000000000000000004220072674642500165200ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyContainer", "type": "object", "required": [ "associated", "generic" ], "properties": { "associated": { "type": "string" }, "generic": { "type": "null" } } }schemars-0.8.16/tests/expected/bytes.json000064400000000000000000000007150072674642500165440ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Tuple_of_Array_of_uint8_and_Array_of_uint8", "type": "array", "items": [ { "type": "array", "items": { "type": "integer", "format": "uint8", "minimum": 0.0 } }, { "type": "array", "items": { "type": "integer", "format": "uint8", "minimum": 0.0 } } ], "maxItems": 2, "minItems": 2 }schemars-0.8.16/tests/expected/chrono-types.json000064400000000000000000000013500072674642500200440ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "ChronoTypes", "type": "object", "required": [ "date_time", "naive_date", "naive_date_time", "naive_time", "weekday" ], "properties": { "weekday": { "type": "string", "enum": [ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" ] }, "date_time": { "type": "string", "format": "date-time" }, "naive_date": { "type": "string", "format": "date" }, "naive_date_time": { "type": "string", "format": "partial-date-time" }, "naive_time": { "type": "string", "format": "partial-date-time" } } }schemars-0.8.16/tests/expected/crate_alias.json000064400000000000000000000004770072674642500176720ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Struct", "type": "object", "required": [ "bar", "foo" ], "properties": { "foo": { "description": "This is a document", "type": "integer", "format": "int32" }, "bar": { "type": "boolean" } } }schemars-0.8.16/tests/expected/default.json000064400000000000000000000016560072674642500170470ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyStruct", "type": "object", "properties": { "my_int": { "default": 0, "type": "integer", "format": "int32" }, "my_bool": { "default": false, "type": "boolean" }, "my_struct2": { "default": "i:0 b:false", "allOf": [ { "$ref": "#/definitions/MyStruct2" } ] }, "my_struct2_default_skipped": { "$ref": "#/definitions/MyStruct2" }, "not_serialize": { "$ref": "#/definitions/NotSerialize" } }, "definitions": { "MyStruct2": { "type": "object", "properties": { "my_int": { "default": 6, "type": "integer", "format": "int32" }, "my_bool": { "default": true, "type": "boolean" } } }, "NotSerialize": { "type": "null" } } }schemars-0.8.16/tests/expected/deprecated-enum.json000064400000000000000000000016410072674642500204570ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "DeprecatedEnum", "deprecated": true, "oneOf": [ { "type": "string", "enum": [ "Unit" ] }, { "deprecated": true, "type": "string", "enum": [ "DeprecatedUnitVariant" ] }, { "deprecated": true, "type": "object", "required": [ "DeprecatedStructVariant" ], "properties": { "DeprecatedStructVariant": { "type": "object", "required": [ "deprecated_field", "foo" ], "properties": { "deprecated_field": { "deprecated": true, "type": "boolean" }, "foo": { "type": "integer", "format": "int32" } } } }, "additionalProperties": false } ] }schemars-0.8.16/tests/expected/deprecated-struct.json000064400000000000000000000005500072674642500210350ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "DeprecatedStruct", "deprecated": true, "type": "object", "required": [ "deprecated_field", "foo" ], "properties": { "foo": { "type": "integer", "format": "int32" }, "deprecated_field": { "deprecated": true, "type": "boolean" } } }schemars-0.8.16/tests/expected/doc_comments_enum.json000064400000000000000000000020740072674642500211140ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "This is the enum's title", "description": "This is the enum's description.", "oneOf": [ { "type": "string", "enum": [ "UndocumentedUnit", "UndocumentedUnit2" ] }, { "description": "This comment is included in the generated schema :)", "type": "string", "enum": [ "DocumentedUnit" ] }, { "title": "Complex variant", "description": "This is a struct-like variant.", "type": "object", "required": [ "Complex" ], "properties": { "Complex": { "type": "object", "properties": { "my_nullable_string": { "title": "A nullable string", "description": "This field is a nullable string.\n\nThis is the second line!\n\nAnd this is the third!", "type": [ "string", "null" ] } } } }, "additionalProperties": false } ] }schemars-0.8.16/tests/expected/doc_comments_override.json000064400000000000000000000006610072674642500217670ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "OverrideDocs struct", "description": "New description", "type": "object", "required": [ "my_int", "my_undocumented_bool" ], "properties": { "my_int": { "title": "My integer", "description": "This is an i32", "type": "integer", "format": "int32" }, "my_undocumented_bool": { "type": "boolean" } } }schemars-0.8.16/tests/expected/doc_comments_struct.json000064400000000000000000000012670072674642500214770ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "This is the struct's title", "description": "This is the struct's description.", "type": "object", "required": [ "my_int", "my_undocumented_bool", "my_unit" ], "properties": { "my_int": { "title": "An integer", "type": "integer", "format": "int32" }, "my_undocumented_bool": { "type": "boolean" }, "my_unit": { "description": "A unit struct instance", "allOf": [ { "$ref": "#/definitions/MyUnitStruct" } ] } }, "definitions": { "MyUnitStruct": { "title": "A Unit", "type": "null" } } }schemars-0.8.16/tests/expected/doc_comments_struct_ref_siblings.json000064400000000000000000000012130072674642500242140ustar 00000000000000{ "$schema": "https://json-schema.org/draft/2019-09/schema", "title": "This is the struct's title", "description": "This is the struct's description.", "type": "object", "required": [ "my_int", "my_undocumented_bool", "my_unit" ], "properties": { "my_int": { "title": "An integer", "type": "integer", "format": "int32" }, "my_undocumented_bool": { "type": "boolean" }, "my_unit": { "description": "A unit struct instance", "$ref": "#/definitions/MyUnitStruct" } }, "definitions": { "MyUnitStruct": { "title": "A Unit", "type": "null" } } }schemars-0.8.16/tests/expected/duration_and_systemtime.json000064400000000000000000000021160072674642500223450ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyStruct", "type": "object", "required": [ "duration", "time" ], "properties": { "duration": { "$ref": "#/definitions/Duration" }, "time": { "$ref": "#/definitions/SystemTime" } }, "definitions": { "Duration": { "type": "object", "required": [ "nanos", "secs" ], "properties": { "secs": { "type": "integer", "format": "uint64", "minimum": 0.0 }, "nanos": { "type": "integer", "format": "uint32", "minimum": 0.0 } } }, "SystemTime": { "type": "object", "required": [ "nanos_since_epoch", "secs_since_epoch" ], "properties": { "secs_since_epoch": { "type": "integer", "format": "uint64", "minimum": 0.0 }, "nanos_since_epoch": { "type": "integer", "format": "uint32", "minimum": 0.0 } } } } }schemars-0.8.16/tests/expected/either.json000064400000000000000000000005020072674642500166700ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Either_int32_or_Either_Boolean_or_Null", "anyOf": [ { "type": "integer", "format": "int32" }, { "anyOf": [ { "type": "boolean" }, { "type": "null" } ] } ] }schemars-0.8.16/tests/expected/enum-adjacent-tagged-duf.json000064400000000000000000000067620072674642500221460ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Adjacent", "oneOf": [ { "type": "object", "required": [ "t" ], "properties": { "t": { "type": "string", "enum": [ "UnitOne" ] } }, "additionalProperties": false }, { "type": "object", "required": [ "c", "t" ], "properties": { "c": { "type": "object", "additionalProperties": { "type": "string" } }, "t": { "type": "string", "enum": [ "StringMap" ] } }, "additionalProperties": false }, { "type": "object", "required": [ "c", "t" ], "properties": { "c": { "$ref": "#/definitions/UnitStruct" }, "t": { "type": "string", "enum": [ "UnitStructNewType" ] } }, "additionalProperties": false }, { "type": "object", "required": [ "c", "t" ], "properties": { "c": { "$ref": "#/definitions/Struct" }, "t": { "type": "string", "enum": [ "StructNewType" ] } }, "additionalProperties": false }, { "type": "object", "required": [ "c", "t" ], "properties": { "c": { "type": "object", "required": [ "bar", "foo" ], "properties": { "bar": { "type": "boolean" }, "foo": { "type": "integer", "format": "int32" } }, "additionalProperties": false }, "t": { "type": "string", "enum": [ "Struct" ] } }, "additionalProperties": false }, { "type": "object", "required": [ "c", "t" ], "properties": { "c": { "type": "array", "items": [ { "type": "integer", "format": "int32" }, { "type": "boolean" } ], "maxItems": 2, "minItems": 2 }, "t": { "type": "string", "enum": [ "Tuple" ] } }, "additionalProperties": false }, { "type": "object", "required": [ "t" ], "properties": { "t": { "type": "string", "enum": [ "UnitTwo" ] } }, "additionalProperties": false }, { "type": "object", "required": [ "c", "t" ], "properties": { "c": { "type": "integer", "format": "int32" }, "t": { "type": "string", "enum": [ "WithInt" ] } }, "additionalProperties": false } ], "definitions": { "Struct": { "type": "object", "required": [ "bar", "foo" ], "properties": { "bar": { "type": "boolean" }, "foo": { "type": "integer", "format": "int32" } } }, "UnitStruct": { "type": "null" } } }schemars-0.8.16/tests/expected/enum-adjacent-tagged.json000064400000000000000000000062410072674642500213620ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Adjacent", "oneOf": [ { "type": "object", "required": [ "t" ], "properties": { "t": { "type": "string", "enum": [ "UnitOne" ] } } }, { "type": "object", "required": [ "c", "t" ], "properties": { "c": { "type": "object", "additionalProperties": { "type": "string" } }, "t": { "type": "string", "enum": [ "StringMap" ] } } }, { "type": "object", "required": [ "c", "t" ], "properties": { "c": { "$ref": "#/definitions/UnitStruct" }, "t": { "type": "string", "enum": [ "UnitStructNewType" ] } } }, { "type": "object", "required": [ "c", "t" ], "properties": { "c": { "$ref": "#/definitions/Struct" }, "t": { "type": "string", "enum": [ "StructNewType" ] } } }, { "type": "object", "required": [ "c", "t" ], "properties": { "c": { "type": "object", "required": [ "bar", "foo" ], "properties": { "bar": { "type": "boolean" }, "foo": { "type": "integer", "format": "int32" } } }, "t": { "type": "string", "enum": [ "Struct" ] } } }, { "type": "object", "required": [ "c", "t" ], "properties": { "c": { "type": "array", "items": [ { "type": "integer", "format": "int32" }, { "type": "boolean" } ], "maxItems": 2, "minItems": 2 }, "t": { "type": "string", "enum": [ "Tuple" ] } } }, { "type": "object", "required": [ "t" ], "properties": { "t": { "type": "string", "enum": [ "UnitTwo" ] } } }, { "type": "object", "required": [ "c", "t" ], "properties": { "c": { "type": "integer", "format": "int32" }, "t": { "type": "string", "enum": [ "WithInt" ] } } } ], "definitions": { "Struct": { "type": "object", "required": [ "bar", "foo" ], "properties": { "bar": { "type": "boolean" }, "foo": { "type": "integer", "format": "int32" } } }, "UnitStruct": { "type": "null" } } }schemars-0.8.16/tests/expected/enum-external-duf.json000064400000000000000000000047350072674642500207640ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "External", "oneOf": [ { "type": "string", "enum": [ "unitOne", "unitTwo" ] }, { "type": "object", "required": [ "stringMap" ], "properties": { "stringMap": { "type": "object", "additionalProperties": { "type": "string" } } }, "additionalProperties": false }, { "type": "object", "required": [ "unitStructNewType" ], "properties": { "unitStructNewType": { "$ref": "#/definitions/UnitStruct" } }, "additionalProperties": false }, { "type": "object", "required": [ "structNewType" ], "properties": { "structNewType": { "$ref": "#/definitions/Struct" } }, "additionalProperties": false }, { "type": "object", "required": [ "struct" ], "properties": { "struct": { "type": "object", "required": [ "bar", "foo" ], "properties": { "bar": { "type": "boolean" }, "foo": { "type": "integer", "format": "int32" } }, "additionalProperties": false } }, "additionalProperties": false }, { "type": "object", "required": [ "tuple" ], "properties": { "tuple": { "type": "array", "items": [ { "type": "integer", "format": "int32" }, { "type": "boolean" } ], "maxItems": 2, "minItems": 2 } }, "additionalProperties": false }, { "type": "object", "required": [ "withInt" ], "properties": { "withInt": { "type": "integer", "format": "int32" } }, "additionalProperties": false } ], "definitions": { "Struct": { "type": "object", "required": [ "bar", "foo" ], "properties": { "bar": { "type": "boolean" }, "foo": { "type": "integer", "format": "int32" } } }, "UnitStruct": { "type": "null" } } }schemars-0.8.16/tests/expected/enum-external.json000064400000000000000000000046640072674642500202110ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "External", "oneOf": [ { "type": "string", "enum": [ "unitOne", "unitTwo" ] }, { "type": "object", "required": [ "stringMap" ], "properties": { "stringMap": { "type": "object", "additionalProperties": { "type": "string" } } }, "additionalProperties": false }, { "type": "object", "required": [ "unitStructNewType" ], "properties": { "unitStructNewType": { "$ref": "#/definitions/UnitStruct" } }, "additionalProperties": false }, { "type": "object", "required": [ "structNewType" ], "properties": { "structNewType": { "$ref": "#/definitions/Struct" } }, "additionalProperties": false }, { "type": "object", "required": [ "struct" ], "properties": { "struct": { "type": "object", "required": [ "bar", "foo" ], "properties": { "bar": { "type": "boolean" }, "foo": { "type": "integer", "format": "int32" } } } }, "additionalProperties": false }, { "type": "object", "required": [ "tuple" ], "properties": { "tuple": { "type": "array", "items": [ { "type": "integer", "format": "int32" }, { "type": "boolean" } ], "maxItems": 2, "minItems": 2 } }, "additionalProperties": false }, { "type": "object", "required": [ "withInt" ], "properties": { "withInt": { "type": "integer", "format": "int32" } }, "additionalProperties": false } ], "definitions": { "Struct": { "type": "object", "required": [ "bar", "foo" ], "properties": { "bar": { "type": "boolean" }, "foo": { "type": "integer", "format": "int32" } } }, "UnitStruct": { "type": "null" } } }schemars-0.8.16/tests/expected/enum-internal-duf.json000064400000000000000000000045750072674642500207600ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Internal", "oneOf": [ { "type": "object", "required": [ "typeProperty" ], "properties": { "typeProperty": { "type": "string", "enum": [ "UnitOne" ] } }, "additionalProperties": false }, { "type": "object", "required": [ "typeProperty" ], "properties": { "typeProperty": { "type": "string", "enum": [ "StringMap" ] } }, "additionalProperties": { "type": "string" } }, { "type": "object", "required": [ "typeProperty" ], "properties": { "typeProperty": { "type": "string", "enum": [ "UnitStructNewType" ] } }, "additionalProperties": false }, { "type": "object", "required": [ "bar", "foo", "typeProperty" ], "properties": { "bar": { "type": "boolean" }, "foo": { "type": "integer", "format": "int32" }, "typeProperty": { "type": "string", "enum": [ "StructNewType" ] } } }, { "type": "object", "required": [ "bar", "foo", "typeProperty" ], "properties": { "bar": { "type": "boolean" }, "foo": { "type": "integer", "format": "int32" }, "typeProperty": { "type": "string", "enum": [ "Struct" ] } }, "additionalProperties": false }, { "type": "object", "required": [ "typeProperty" ], "properties": { "typeProperty": { "type": "string", "enum": [ "UnitTwo" ] } }, "additionalProperties": false }, { "type": [ "object", "integer" ], "format": "int32", "required": [ "typeProperty" ], "properties": { "typeProperty": { "type": "string", "enum": [ "WithInt" ] } }, "additionalProperties": false } ] }schemars-0.8.16/tests/expected/enum-internal.json000064400000000000000000000042020072674642500201670ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Internal", "oneOf": [ { "type": "object", "required": [ "typeProperty" ], "properties": { "typeProperty": { "type": "string", "enum": [ "UnitOne" ] } } }, { "type": "object", "required": [ "typeProperty" ], "properties": { "typeProperty": { "type": "string", "enum": [ "StringMap" ] } } }, { "type": "object", "required": [ "typeProperty" ], "properties": { "typeProperty": { "type": "string", "enum": [ "UnitStructNewType" ] } } }, { "type": "object", "required": [ "bar", "foo", "typeProperty" ], "properties": { "bar": { "type": "boolean" }, "foo": { "type": "integer", "format": "int32" }, "typeProperty": { "type": "string", "enum": [ "StructNewType" ] } } }, { "type": "object", "required": [ "bar", "foo", "typeProperty" ], "properties": { "bar": { "type": "boolean" }, "foo": { "type": "integer", "format": "int32" }, "typeProperty": { "type": "string", "enum": [ "Struct" ] } } }, { "type": "object", "required": [ "typeProperty" ], "properties": { "typeProperty": { "type": "string", "enum": [ "UnitTwo" ] } } }, { "type": [ "object", "integer" ], "format": "int32", "required": [ "typeProperty" ], "properties": { "typeProperty": { "type": "string", "enum": [ "WithInt" ] } } } ] }schemars-0.8.16/tests/expected/enum-repr-with-attrs.json000064400000000000000000000003050072674642500214270ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Renamed", "description": "Description from comment", "type": "integer", "enum": [ 0, 1, 5, 6, 3 ] }schemars-0.8.16/tests/expected/enum-repr.json000064400000000000000000000002250072674642500173240ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Enum", "type": "integer", "enum": [ 0, 1, 5, 6, 3 ] }schemars-0.8.16/tests/expected/enum-simple-internal-duf.json000064400000000000000000000016140072674642500222360ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "SimpleInternal", "oneOf": [ { "type": "object", "required": [ "typeProperty" ], "properties": { "typeProperty": { "type": "string", "enum": [ "A" ] } }, "additionalProperties": false }, { "type": "object", "required": [ "typeProperty" ], "properties": { "typeProperty": { "type": "string", "enum": [ "B" ] } }, "additionalProperties": false }, { "type": "object", "required": [ "typeProperty" ], "properties": { "typeProperty": { "type": "string", "enum": [ "C" ] } }, "additionalProperties": false } ] }schemars-0.8.16/tests/expected/enum-simple-internal.json000064400000000000000000000014350072674642500214630ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "SimpleInternal", "oneOf": [ { "type": "object", "required": [ "typeProperty" ], "properties": { "typeProperty": { "type": "string", "enum": [ "A" ] } } }, { "type": "object", "required": [ "typeProperty" ], "properties": { "typeProperty": { "type": "string", "enum": [ "B" ] } } }, { "type": "object", "required": [ "typeProperty" ], "properties": { "typeProperty": { "type": "string", "enum": [ "C" ] } } } ] }schemars-0.8.16/tests/expected/enum-unit-doc.json000064400000000000000000000007350072674642500201040ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "SoundOfMusic", "oneOf": [ { "title": "A deer", "description": "A female deer", "type": "string", "enum": [ "Do" ] }, { "description": "A drop of golden sun", "type": "string", "enum": [ "Re" ] }, { "description": "A name I call myself", "type": "string", "enum": [ "Mi" ] } ] }schemars-0.8.16/tests/expected/enum-untagged-duf.json000064400000000000000000000023750072674642500207360ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Untagged", "anyOf": [ { "type": "null" }, { "type": "object", "additionalProperties": { "type": "string" } }, { "$ref": "#/definitions/UnitStruct" }, { "$ref": "#/definitions/Struct" }, { "type": "object", "required": [ "bar", "foo" ], "properties": { "foo": { "type": "integer", "format": "int32" }, "bar": { "type": "boolean" } }, "additionalProperties": false }, { "type": "array", "items": [ { "type": "integer", "format": "int32" }, { "type": "boolean" } ], "maxItems": 2, "minItems": 2 }, { "type": "integer", "format": "int32" } ], "definitions": { "UnitStruct": { "type": "null" }, "Struct": { "type": "object", "required": [ "bar", "foo" ], "properties": { "foo": { "type": "integer", "format": "int32" }, "bar": { "type": "boolean" } } } } }schemars-0.8.16/tests/expected/enum-untagged.json000064400000000000000000000023300072674642500201510ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Untagged", "anyOf": [ { "type": "null" }, { "type": "object", "additionalProperties": { "type": "string" } }, { "$ref": "#/definitions/UnitStruct" }, { "$ref": "#/definitions/Struct" }, { "type": "object", "required": [ "bar", "foo" ], "properties": { "foo": { "type": "integer", "format": "int32" }, "bar": { "type": "boolean" } } }, { "type": "array", "items": [ { "type": "integer", "format": "int32" }, { "type": "boolean" } ], "maxItems": 2, "minItems": 2 }, { "type": "integer", "format": "int32" } ], "definitions": { "UnitStruct": { "type": "null" }, "Struct": { "type": "object", "required": [ "bar", "foo" ], "properties": { "foo": { "type": "integer", "format": "int32" }, "bar": { "type": "boolean" } } } } }schemars-0.8.16/tests/expected/enumset.json000064400000000000000000000004500072674642500170720ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Set_of_Foo", "type": "array", "items": { "$ref": "#/definitions/Foo" }, "uniqueItems": true, "definitions": { "Foo": { "type": "string", "enum": [ "Bar", "Baz" ] } } } schemars-0.8.16/tests/expected/examples.json000064400000000000000000000010410072674642500172250ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Struct", "examples": [ { "bar": false, "baz": null, "foo": 0 }, null ], "type": "object", "required": [ "bar", "foo" ], "properties": { "foo": { "examples": [ 8, null ], "type": "integer", "format": "int32" }, "bar": { "type": "boolean" }, "baz": { "examples": [ null ], "type": [ "string", "null" ] } } }schemars-0.8.16/tests/expected/flatten.json000064400000000000000000000007720072674642500170560ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Flat", "type": "object", "required": [ "b", "f", "s", "v" ], "properties": { "f": { "type": "number", "format": "float" }, "b": { "type": "boolean" }, "s": { "type": "string" }, "os": { "default": "", "type": "string" }, "v": { "type": "array", "items": { "type": "integer", "format": "int32" } } } }schemars-0.8.16/tests/expected/from_json_value.json000064400000000000000000000014310072674642500206020ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "examples": [ { "bool": true, "minusOne": -1, "null": null, "object": { "array": [ "foo", "bar" ] }, "one": 1, "zero": 0, "zeroPointZero": 0.0 } ], "type": "object", "properties": { "bool": { "type": "boolean" }, "minusOne": { "type": "integer" }, "null": true, "object": { "type": "object", "properties": { "array": { "type": "array", "items": { "type": "string" } } } }, "one": { "type": "integer" }, "zero": { "type": "integer" }, "zeroPointZero": { "type": "number" } } }schemars-0.8.16/tests/expected/from_value_2019_09.json000064400000000000000000000027050072674642500205410ustar 00000000000000{ "$schema": "https://json-schema.org/draft/2019-09/schema", "title": "MyStruct", "examples": [ { "myBool": true, "myInnerStruct": { "my_empty_map": {}, "my_empty_vec": [], "my_map": { "": 0.0 }, "my_tuple": [ "💩", 42 ], "my_vec": [ "hello", "world" ] }, "myInt": 123, "myNullableEnum": null } ], "type": "object", "properties": { "myInt": { "type": "integer" }, "myBool": { "type": "boolean" }, "myNullableEnum": true, "myInnerStruct": { "type": "object", "properties": { "my_map": { "type": "object", "additionalProperties": { "type": "number" } }, "my_vec": { "type": "array", "items": { "type": "string" } }, "my_empty_map": { "type": "object", "additionalProperties": true }, "my_empty_vec": { "type": "array", "items": true }, "my_tuple": { "type": "array", "items": [ { "type": "string", "maxLength": 1, "minLength": 1 }, { "type": "integer" } ], "maxItems": 2, "minItems": 2 } } } } }schemars-0.8.16/tests/expected/from_value_draft07.json000064400000000000000000000027000072674642500211000ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyStruct", "examples": [ { "myBool": true, "myInnerStruct": { "my_empty_map": {}, "my_empty_vec": [], "my_map": { "": 0.0 }, "my_tuple": [ "💩", 42 ], "my_vec": [ "hello", "world" ] }, "myInt": 123, "myNullableEnum": null } ], "type": "object", "properties": { "myInt": { "type": "integer" }, "myBool": { "type": "boolean" }, "myNullableEnum": true, "myInnerStruct": { "type": "object", "properties": { "my_map": { "type": "object", "additionalProperties": { "type": "number" } }, "my_vec": { "type": "array", "items": { "type": "string" } }, "my_empty_map": { "type": "object", "additionalProperties": true }, "my_empty_vec": { "type": "array", "items": true }, "my_tuple": { "type": "array", "items": [ { "type": "string", "maxLength": 1, "minLength": 1 }, { "type": "integer" } ], "maxItems": 2, "minItems": 2 } } } } }schemars-0.8.16/tests/expected/from_value_openapi3.json000064400000000000000000000027070072674642500213560ustar 00000000000000{ "$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema", "title": "MyStruct", "type": "object", "properties": { "myInt": { "type": "integer" }, "myBool": { "type": "boolean" }, "myNullableEnum": { "nullable": true }, "myInnerStruct": { "type": "object", "properties": { "my_map": { "type": "object", "additionalProperties": { "type": "number" } }, "my_vec": { "type": "array", "items": { "type": "string" } }, "my_empty_map": { "type": "object", "additionalProperties": true }, "my_empty_vec": { "type": "array", "items": {} }, "my_tuple": { "type": "array", "items": [ { "type": "string", "maxLength": 1, "minLength": 1 }, { "type": "integer" } ], "maxItems": 2, "minItems": 2 } } } }, "example": { "myBool": true, "myInnerStruct": { "my_empty_map": {}, "my_empty_vec": [], "my_map": { "": 0.0 }, "my_tuple": [ "💩", 42 ], "my_vec": [ "hello", "world" ] }, "myInt": 123, "myNullableEnum": null } }schemars-0.8.16/tests/expected/indexmap.json000064400000000000000000000006520072674642500172230ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "IndexMapTypes", "type": "object", "required": [ "map", "set" ], "properties": { "map": { "type": "object", "additionalProperties": { "type": "boolean" } }, "set": { "type": "array", "items": { "type": "integer", "format": "int" }, "uniqueItems": true } } }schemars-0.8.16/tests/expected/inline-subschemas-recursive.json000064400000000000000000000021720072674642500230330ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "RecursiveOuter", "type": "object", "properties": { "direct": { "anyOf": [ { "$ref": "#/definitions/RecursiveOuter" }, { "type": "null" } ] }, "indirect": { "type": [ "object", "null" ], "required": [ "recursive" ], "properties": { "recursive": { "$ref": "#/definitions/RecursiveOuter" } } } }, "definitions": { "RecursiveOuter": { "type": "object", "properties": { "direct": { "anyOf": [ { "$ref": "#/definitions/RecursiveOuter" }, { "type": "null" } ] }, "indirect": { "type": [ "object", "null" ], "required": [ "recursive" ], "properties": { "recursive": { "$ref": "#/definitions/RecursiveOuter" } } } } } } }schemars-0.8.16/tests/expected/inline-subschemas.json000064400000000000000000000006070072674642500210270ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyJob", "type": "object", "required": [ "spec" ], "properties": { "spec": { "type": "object", "required": [ "replicas" ], "properties": { "replicas": { "type": "integer", "format": "uint32", "minimum": 0.0 } } } } }schemars-0.8.16/tests/expected/macro_built_enum.json000064400000000000000000000010630072674642500207370ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "OuterEnum", "oneOf": [ { "type": "object", "required": [ "InnerStruct" ], "properties": { "InnerStruct": { "$ref": "#/definitions/InnerStruct" } }, "additionalProperties": false } ], "definitions": { "InnerStruct": { "type": "object", "required": [ "x" ], "properties": { "x": { "type": "integer", "format": "int32" } } } } }schemars-0.8.16/tests/expected/macro_built_struct.json000064400000000000000000000004660072674642500213250ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "A", "type": "object", "required": [ "v", "x" ], "properties": { "x": { "type": "integer", "format": "uint8", "minimum": 0.0 }, "v": { "type": "integer", "format": "int32" } } }schemars-0.8.16/tests/expected/nonzero_ints.json000064400000000000000000000011500072674642500201370ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyStruct", "type": "object", "required": [ "nonzero_signed", "nonzero_unsigned", "signed", "unsigned" ], "properties": { "unsigned": { "type": "integer", "format": "uint32", "minimum": 0.0 }, "nonzero_unsigned": { "type": "integer", "format": "uint32", "minimum": 1.0 }, "signed": { "type": "integer", "format": "int32" }, "nonzero_signed": { "type": "integer", "format": "int32", "not": { "const": 0 } } } }schemars-0.8.16/tests/expected/os_strings.json000064400000000000000000000020710072674642500176050ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "OsStrings", "type": "object", "required": [ "borrowed", "owned" ], "properties": { "owned": { "$ref": "#/definitions/OsString" }, "borrowed": { "$ref": "#/definitions/OsString" } }, "definitions": { "OsString": { "oneOf": [ { "type": "object", "required": [ "Unix" ], "properties": { "Unix": { "type": "array", "items": { "type": "integer", "format": "uint8", "minimum": 0.0 } } } }, { "type": "object", "required": [ "Windows" ], "properties": { "Windows": { "type": "array", "items": { "type": "integer", "format": "uint16", "minimum": 0.0 } } } } ] } } }schemars-0.8.16/tests/expected/property-name-struct.json000064400000000000000000000006470072674642500215460ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyStruct", "type": "object", "required": [ "camelCase", "new_name_1", "new_name_2" ], "properties": { "camelCase": { "type": "integer", "format": "int32" }, "new_name_1": { "type": "integer", "format": "int32" }, "new_name_2": { "type": "integer", "format": "int32" } } }schemars-0.8.16/tests/expected/range.json000064400000000000000000000032050072674642500165070ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyStruct", "type": "object", "required": [ "bound", "inclusive", "range" ], "properties": { "range": { "$ref": "#/definitions/Range_of_uint" }, "inclusive": { "$ref": "#/definitions/Range_of_double" }, "bound": { "$ref": "#/definitions/Bound_of_String" } }, "definitions": { "Range_of_uint": { "type": "object", "required": [ "end", "start" ], "properties": { "start": { "type": "integer", "format": "uint", "minimum": 0.0 }, "end": { "type": "integer", "format": "uint", "minimum": 0.0 } } }, "Range_of_double": { "type": "object", "required": [ "end", "start" ], "properties": { "start": { "type": "number", "format": "double" }, "end": { "type": "number", "format": "double" } } }, "Bound_of_String": { "oneOf": [ { "type": "object", "required": [ "Included" ], "properties": { "Included": { "type": "string" } } }, { "type": "object", "required": [ "Excluded" ], "properties": { "Excluded": { "type": "string" } } }, { "type": "string", "const": "Unbounded" } ] } } }schemars-0.8.16/tests/expected/remote_derive.json000064400000000000000000000017100072674642500202430ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Process", "type": "object", "required": [ "command_line", "wall_time" ], "properties": { "command_line": { "type": "string" }, "wall_time": { "$ref": "#/definitions/Duration" }, "user_cpu_time": { "default": { "nanos": 0, "secs": 0 }, "allOf": [ { "$ref": "#/definitions/Duration" } ] }, "system_cpu_time": { "default": "0.000000000s", "allOf": [ { "$ref": "#/definitions/Duration" } ] } }, "definitions": { "Duration": { "type": "object", "required": [ "nanos", "secs" ], "properties": { "secs": { "type": "integer", "format": "int64" }, "nanos": { "type": "integer", "format": "int32" } } } } }schemars-0.8.16/tests/expected/remote_derive_generic.json000064400000000000000000000021160072674642500217400ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyStruct_for_int32", "type": "object", "required": [ "byte_or_bool2", "fake_map", "s", "unit_or_t2" ], "properties": { "byte_or_bool2": { "$ref": "#/definitions/Or_for_uint8_and_Boolean" }, "unit_or_t2": { "$ref": "#/definitions/Or_for_Null_and_int32" }, "s": { "$ref": "#/definitions/Str" }, "fake_map": { "type": "object", "additionalProperties": { "type": "array", "items": { "type": "string" }, "uniqueItems": true } } }, "definitions": { "Or_for_uint8_and_Boolean": { "anyOf": [ { "type": "integer", "format": "uint8", "minimum": 0.0 }, { "type": "boolean" } ] }, "Or_for_Null_and_int32": { "anyOf": [ { "type": "null" }, { "type": "integer", "format": "int32" } ] }, "Str": { "type": "string" } } }schemars-0.8.16/tests/expected/result.json000064400000000000000000000031440072674642500167330ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Container", "type": "object", "required": [ "result1", "result2" ], "properties": { "result1": { "$ref": "#/definitions/Result_of_MyStruct_or_Array_of_String" }, "result2": { "$ref": "#/definitions/Result_of_Boolean_or_Null" } }, "definitions": { "Result_of_MyStruct_or_Array_of_String": { "oneOf": [ { "type": "object", "required": [ "Ok" ], "properties": { "Ok": { "$ref": "#/definitions/MyStruct" } } }, { "type": "object", "required": [ "Err" ], "properties": { "Err": { "type": "array", "items": { "type": "string" } } } } ] }, "MyStruct": { "type": "object", "required": [ "foo" ], "properties": { "foo": { "type": "integer", "format": "int32" } } }, "Result_of_Boolean_or_Null": { "oneOf": [ { "type": "object", "required": [ "Ok" ], "properties": { "Ok": { "type": "boolean" } } }, { "type": "object", "required": [ "Err" ], "properties": { "Err": { "type": "null" } } } ] } } }schemars-0.8.16/tests/expected/rust_decimal.json000064400000000000000000000002130072674642500200620ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Decimal", "type": "string", "pattern": "^-?[0-9]+(\\.[0-9]+)?$" }schemars-0.8.16/tests/expected/same_name.json000064400000000000000000000012310072674642500173350ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Config2", "type": "object", "required": [ "a_cfg", "b_cfg" ], "properties": { "a_cfg": { "$ref": "#/definitions/Config" }, "b_cfg": { "$ref": "#/definitions/Config2" } }, "definitions": { "Config": { "type": "object", "required": [ "test" ], "properties": { "test": { "type": "string" } } }, "Config2": { "type": "object", "required": [ "test2" ], "properties": { "test2": { "type": "string" } } } } }schemars-0.8.16/tests/expected/schema-2019_09.json000064400000000000000000000702770072674642500175710ustar 00000000000000{ "$schema": "https://json-schema.org/draft/2019-09/schema", "title": "RootSchema", "description": "The root object of a JSON Schema document.", "type": "object", "properties": { "$schema": { "description": "The `$schema` keyword.\n\nSee [JSON Schema 8.1.1. The \"$schema\" Keyword](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.1.1).", "type": [ "string", "null" ] }, "definitions": { "description": "The `definitions` keyword.\n\nIn JSON Schema draft 2019-09 this was replaced by $defs, but in Schemars this is still serialized as `definitions` for backward-compatibility.\n\nSee [JSON Schema 8.2.5. Schema Re-Use With \"$defs\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.5), and [JSON Schema (draft 07) 9. Schema Re-Use With \"definitions\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-9).", "type": "object", "additionalProperties": { "$ref": "#/definitions/Schema" } }, "type": { "description": "The `type` keyword.\n\nSee [JSON Schema Validation 6.1.1. \"type\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.1) and [JSON Schema 4.2.1. Instance Data Model](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-4.2.1).", "anyOf": [ { "$ref": "#/definitions/SingleOrVec_for_InstanceType" }, { "type": "null" } ] }, "format": { "description": "The `format` keyword.\n\nSee [JSON Schema Validation 7. A Vocabulary for Semantic Content With \"format\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-7).", "type": [ "string", "null" ] }, "enum": { "description": "The `enum` keyword.\n\nSee [JSON Schema Validation 6.1.2. \"enum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.2)", "type": [ "array", "null" ], "items": true }, "const": { "description": "The `const` keyword.\n\nSee [JSON Schema Validation 6.1.3. \"const\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.3)" }, "$ref": { "description": "The `$ref` keyword.\n\nSee [JSON Schema 8.2.4.1. Direct References with \"$ref\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.4.1).", "type": [ "string", "null" ] }, "$id": { "description": "The `$id` keyword.\n\nSee [JSON Schema 8.2.2. The \"$id\" Keyword](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.2).", "type": [ "string", "null" ] }, "title": { "description": "The `title` keyword.\n\nSee [JSON Schema Validation 9.1. \"title\" and \"description\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.1).", "type": [ "string", "null" ] }, "description": { "description": "The `description` keyword.\n\nSee [JSON Schema Validation 9.1. \"title\" and \"description\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.1).", "type": [ "string", "null" ] }, "default": { "description": "The `default` keyword.\n\nSee [JSON Schema Validation 9.2. \"default\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.2)." }, "deprecated": { "description": "The `deprecated` keyword.\n\nSee [JSON Schema Validation 9.3. \"deprecated\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.3).", "type": "boolean" }, "readOnly": { "description": "The `readOnly` keyword.\n\nSee [JSON Schema Validation 9.4. \"readOnly\" and \"writeOnly\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.4).", "type": "boolean" }, "writeOnly": { "description": "The `writeOnly` keyword.\n\nSee [JSON Schema Validation 9.4. \"readOnly\" and \"writeOnly\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.4).", "type": "boolean" }, "examples": { "description": "The `examples` keyword.\n\nSee [JSON Schema Validation 9.5. \"examples\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.5).", "type": "array", "items": true }, "allOf": { "description": "The `allOf` keyword.\n\nSee [JSON Schema 9.2.1.1. \"allOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.1).", "type": [ "array", "null" ], "items": { "$ref": "#/definitions/Schema" } }, "anyOf": { "description": "The `anyOf` keyword.\n\nSee [JSON Schema 9.2.1.2. \"anyOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.2).", "type": [ "array", "null" ], "items": { "$ref": "#/definitions/Schema" } }, "oneOf": { "description": "The `oneOf` keyword.\n\nSee [JSON Schema 9.2.1.3. \"oneOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.3).", "type": [ "array", "null" ], "items": { "$ref": "#/definitions/Schema" } }, "not": { "description": "The `not` keyword.\n\nSee [JSON Schema 9.2.1.4. \"not\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.4).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "if": { "description": "The `if` keyword.\n\nSee [JSON Schema 9.2.2.1. \"if\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.1).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "then": { "description": "The `then` keyword.\n\nSee [JSON Schema 9.2.2.2. \"then\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.2).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "else": { "description": "The `else` keyword.\n\nSee [JSON Schema 9.2.2.3. \"else\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.3).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "multipleOf": { "description": "The `multipleOf` keyword.\n\nSee [JSON Schema Validation 6.2.1. \"multipleOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.1).", "type": [ "number", "null" ], "format": "double" }, "maximum": { "description": "The `maximum` keyword.\n\nSee [JSON Schema Validation 6.2.2. \"maximum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.2).", "type": [ "number", "null" ], "format": "double" }, "exclusiveMaximum": { "description": "The `exclusiveMaximum` keyword.\n\nSee [JSON Schema Validation 6.2.3. \"exclusiveMaximum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.3).", "type": [ "number", "null" ], "format": "double" }, "minimum": { "description": "The `minimum` keyword.\n\nSee [JSON Schema Validation 6.2.4. \"minimum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.4).", "type": [ "number", "null" ], "format": "double" }, "exclusiveMinimum": { "description": "The `exclusiveMinimum` keyword.\n\nSee [JSON Schema Validation 6.2.5. \"exclusiveMinimum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.5).", "type": [ "number", "null" ], "format": "double" }, "maxLength": { "description": "The `maxLength` keyword.\n\nSee [JSON Schema Validation 6.3.1. \"maxLength\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.1).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "minLength": { "description": "The `minLength` keyword.\n\nSee [JSON Schema Validation 6.3.2. \"minLength\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.2).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "pattern": { "description": "The `pattern` keyword.\n\nSee [JSON Schema Validation 6.3.3. \"pattern\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.3).", "type": [ "string", "null" ] }, "items": { "description": "The `items` keyword.\n\nSee [JSON Schema 9.3.1.1. \"items\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.1).", "anyOf": [ { "$ref": "#/definitions/SingleOrVec_for_Schema" }, { "type": "null" } ] }, "additionalItems": { "description": "The `additionalItems` keyword.\n\nSee [JSON Schema 9.3.1.2. \"additionalItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.2).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "maxItems": { "description": "The `maxItems` keyword.\n\nSee [JSON Schema Validation 6.4.1. \"maxItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.1).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "minItems": { "description": "The `minItems` keyword.\n\nSee [JSON Schema Validation 6.4.2. \"minItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.2).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "uniqueItems": { "description": "The `uniqueItems` keyword.\n\nSee [JSON Schema Validation 6.4.3. \"uniqueItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.3).", "type": [ "boolean", "null" ] }, "contains": { "description": "The `contains` keyword.\n\nSee [JSON Schema 9.3.1.4. \"contains\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.4).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "maxProperties": { "description": "The `maxProperties` keyword.\n\nSee [JSON Schema Validation 6.5.1. \"maxProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.1).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "minProperties": { "description": "The `minProperties` keyword.\n\nSee [JSON Schema Validation 6.5.2. \"minProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.2).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "required": { "description": "The `required` keyword.\n\nSee [JSON Schema Validation 6.5.3. \"required\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.3).", "type": "array", "items": { "type": "string" }, "uniqueItems": true }, "properties": { "description": "The `properties` keyword.\n\nSee [JSON Schema 9.3.2.1. \"properties\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.1).", "type": "object", "additionalProperties": { "$ref": "#/definitions/Schema" } }, "patternProperties": { "description": "The `patternProperties` keyword.\n\nSee [JSON Schema 9.3.2.2. \"patternProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.2).", "type": "object", "additionalProperties": { "$ref": "#/definitions/Schema" } }, "additionalProperties": { "description": "The `additionalProperties` keyword.\n\nSee [JSON Schema 9.3.2.3. \"additionalProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.3).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "propertyNames": { "description": "The `propertyNames` keyword.\n\nSee [JSON Schema 9.3.2.5. \"propertyNames\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.5).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] } }, "additionalProperties": true, "definitions": { "Schema": { "description": "A JSON Schema.", "anyOf": [ { "description": "A trivial boolean JSON Schema.\n\nThe schema `true` matches everything (always passes validation), whereas the schema `false` matches nothing (always fails validation).", "type": "boolean" }, { "description": "A JSON Schema object.", "$ref": "#/definitions/SchemaObject" } ] }, "SchemaObject": { "description": "A JSON Schema object.", "type": "object", "properties": { "type": { "description": "The `type` keyword.\n\nSee [JSON Schema Validation 6.1.1. \"type\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.1) and [JSON Schema 4.2.1. Instance Data Model](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-4.2.1).", "anyOf": [ { "$ref": "#/definitions/SingleOrVec_for_InstanceType" }, { "type": "null" } ] }, "format": { "description": "The `format` keyword.\n\nSee [JSON Schema Validation 7. A Vocabulary for Semantic Content With \"format\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-7).", "type": [ "string", "null" ] }, "enum": { "description": "The `enum` keyword.\n\nSee [JSON Schema Validation 6.1.2. \"enum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.2)", "type": [ "array", "null" ], "items": true }, "const": { "description": "The `const` keyword.\n\nSee [JSON Schema Validation 6.1.3. \"const\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.3)" }, "$ref": { "description": "The `$ref` keyword.\n\nSee [JSON Schema 8.2.4.1. Direct References with \"$ref\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.4.1).", "type": [ "string", "null" ] }, "$id": { "description": "The `$id` keyword.\n\nSee [JSON Schema 8.2.2. The \"$id\" Keyword](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.2).", "type": [ "string", "null" ] }, "title": { "description": "The `title` keyword.\n\nSee [JSON Schema Validation 9.1. \"title\" and \"description\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.1).", "type": [ "string", "null" ] }, "description": { "description": "The `description` keyword.\n\nSee [JSON Schema Validation 9.1. \"title\" and \"description\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.1).", "type": [ "string", "null" ] }, "default": { "description": "The `default` keyword.\n\nSee [JSON Schema Validation 9.2. \"default\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.2)." }, "deprecated": { "description": "The `deprecated` keyword.\n\nSee [JSON Schema Validation 9.3. \"deprecated\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.3).", "type": "boolean" }, "readOnly": { "description": "The `readOnly` keyword.\n\nSee [JSON Schema Validation 9.4. \"readOnly\" and \"writeOnly\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.4).", "type": "boolean" }, "writeOnly": { "description": "The `writeOnly` keyword.\n\nSee [JSON Schema Validation 9.4. \"readOnly\" and \"writeOnly\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.4).", "type": "boolean" }, "examples": { "description": "The `examples` keyword.\n\nSee [JSON Schema Validation 9.5. \"examples\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.5).", "type": "array", "items": true }, "allOf": { "description": "The `allOf` keyword.\n\nSee [JSON Schema 9.2.1.1. \"allOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.1).", "type": [ "array", "null" ], "items": { "$ref": "#/definitions/Schema" } }, "anyOf": { "description": "The `anyOf` keyword.\n\nSee [JSON Schema 9.2.1.2. \"anyOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.2).", "type": [ "array", "null" ], "items": { "$ref": "#/definitions/Schema" } }, "oneOf": { "description": "The `oneOf` keyword.\n\nSee [JSON Schema 9.2.1.3. \"oneOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.3).", "type": [ "array", "null" ], "items": { "$ref": "#/definitions/Schema" } }, "not": { "description": "The `not` keyword.\n\nSee [JSON Schema 9.2.1.4. \"not\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.4).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "if": { "description": "The `if` keyword.\n\nSee [JSON Schema 9.2.2.1. \"if\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.1).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "then": { "description": "The `then` keyword.\n\nSee [JSON Schema 9.2.2.2. \"then\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.2).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "else": { "description": "The `else` keyword.\n\nSee [JSON Schema 9.2.2.3. \"else\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.3).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "multipleOf": { "description": "The `multipleOf` keyword.\n\nSee [JSON Schema Validation 6.2.1. \"multipleOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.1).", "type": [ "number", "null" ], "format": "double" }, "maximum": { "description": "The `maximum` keyword.\n\nSee [JSON Schema Validation 6.2.2. \"maximum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.2).", "type": [ "number", "null" ], "format": "double" }, "exclusiveMaximum": { "description": "The `exclusiveMaximum` keyword.\n\nSee [JSON Schema Validation 6.2.3. \"exclusiveMaximum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.3).", "type": [ "number", "null" ], "format": "double" }, "minimum": { "description": "The `minimum` keyword.\n\nSee [JSON Schema Validation 6.2.4. \"minimum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.4).", "type": [ "number", "null" ], "format": "double" }, "exclusiveMinimum": { "description": "The `exclusiveMinimum` keyword.\n\nSee [JSON Schema Validation 6.2.5. \"exclusiveMinimum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.5).", "type": [ "number", "null" ], "format": "double" }, "maxLength": { "description": "The `maxLength` keyword.\n\nSee [JSON Schema Validation 6.3.1. \"maxLength\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.1).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "minLength": { "description": "The `minLength` keyword.\n\nSee [JSON Schema Validation 6.3.2. \"minLength\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.2).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "pattern": { "description": "The `pattern` keyword.\n\nSee [JSON Schema Validation 6.3.3. \"pattern\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.3).", "type": [ "string", "null" ] }, "items": { "description": "The `items` keyword.\n\nSee [JSON Schema 9.3.1.1. \"items\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.1).", "anyOf": [ { "$ref": "#/definitions/SingleOrVec_for_Schema" }, { "type": "null" } ] }, "additionalItems": { "description": "The `additionalItems` keyword.\n\nSee [JSON Schema 9.3.1.2. \"additionalItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.2).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "maxItems": { "description": "The `maxItems` keyword.\n\nSee [JSON Schema Validation 6.4.1. \"maxItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.1).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "minItems": { "description": "The `minItems` keyword.\n\nSee [JSON Schema Validation 6.4.2. \"minItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.2).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "uniqueItems": { "description": "The `uniqueItems` keyword.\n\nSee [JSON Schema Validation 6.4.3. \"uniqueItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.3).", "type": [ "boolean", "null" ] }, "contains": { "description": "The `contains` keyword.\n\nSee [JSON Schema 9.3.1.4. \"contains\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.4).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "maxProperties": { "description": "The `maxProperties` keyword.\n\nSee [JSON Schema Validation 6.5.1. \"maxProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.1).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "minProperties": { "description": "The `minProperties` keyword.\n\nSee [JSON Schema Validation 6.5.2. \"minProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.2).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "required": { "description": "The `required` keyword.\n\nSee [JSON Schema Validation 6.5.3. \"required\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.3).", "type": "array", "items": { "type": "string" }, "uniqueItems": true }, "properties": { "description": "The `properties` keyword.\n\nSee [JSON Schema 9.3.2.1. \"properties\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.1).", "type": "object", "additionalProperties": { "$ref": "#/definitions/Schema" } }, "patternProperties": { "description": "The `patternProperties` keyword.\n\nSee [JSON Schema 9.3.2.2. \"patternProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.2).", "type": "object", "additionalProperties": { "$ref": "#/definitions/Schema" } }, "additionalProperties": { "description": "The `additionalProperties` keyword.\n\nSee [JSON Schema 9.3.2.3. \"additionalProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.3).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "propertyNames": { "description": "The `propertyNames` keyword.\n\nSee [JSON Schema 9.3.2.5. \"propertyNames\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.5).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] } }, "additionalProperties": true }, "SingleOrVec_for_InstanceType": { "description": "A type which can be serialized as a single item, or multiple items.\n\nIn some contexts, a `Single` may be semantically distinct from a `Vec` containing only item.", "anyOf": [ { "$ref": "#/definitions/InstanceType" }, { "type": "array", "items": { "$ref": "#/definitions/InstanceType" } } ] }, "InstanceType": { "description": "The possible types of values in JSON Schema documents.\n\nSee [JSON Schema 4.2.1. Instance Data Model](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-4.2.1).", "type": "string", "enum": [ "null", "boolean", "object", "array", "number", "string", "integer" ] }, "SingleOrVec_for_Schema": { "description": "A type which can be serialized as a single item, or multiple items.\n\nIn some contexts, a `Single` may be semantically distinct from a `Vec` containing only item.", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "array", "items": { "$ref": "#/definitions/Schema" } } ] } } }schemars-0.8.16/tests/expected/schema-name-const-generics.json000064400000000000000000000003520072674642500225120ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "const-generics-z-42", "type": "object", "required": [ "foo" ], "properties": { "foo": { "type": "integer", "format": "int32" } } }schemars-0.8.16/tests/expected/schema-name-custom.json000064400000000000000000000013770072674642500211110ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "a-new-name-Array_of_String-int32-int32", "type": "object", "required": [ "inner", "t", "u", "v", "w" ], "properties": { "t": { "type": "integer", "format": "int32" }, "u": { "type": "null" }, "v": { "type": "boolean" }, "w": { "type": "array", "items": { "type": "string" } }, "inner": { "$ref": "#/definitions/another-new-name" } }, "definitions": { "another-new-name": { "type": "object", "required": [ "foo" ], "properties": { "foo": { "type": "integer", "format": "int32" } } } } }schemars-0.8.16/tests/expected/schema-name-default.json000064400000000000000000000014200072674642500212100ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyStruct_for_int32_and_Null_and_Boolean_and_Array_of_String", "type": "object", "required": [ "inner", "t", "u", "v", "w" ], "properties": { "t": { "type": "integer", "format": "int32" }, "u": { "type": "null" }, "v": { "type": "boolean" }, "w": { "type": "array", "items": { "type": "string" } }, "inner": { "$ref": "#/definitions/MySimpleStruct" } }, "definitions": { "MySimpleStruct": { "type": "object", "required": [ "foo" ], "properties": { "foo": { "type": "integer", "format": "int32" } } } } }schemars-0.8.16/tests/expected/schema-name-mixed-generics.json000064400000000000000000000024020072674642500224700ustar 00000000000000{ "$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", "type": "object", "required": [ "foo", "generic" ], "properties": { "foo": { "type": "integer", "format": "int32" }, "generic": { "$ref": "#/definitions/MyStruct_for_int32_and_Null_and_Boolean_and_Array_of_String" } }, "definitions": { "MySimpleStruct": { "type": "object", "required": [ "foo" ], "properties": { "foo": { "type": "integer", "format": "int32" } } }, "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" }, "u": { "type": "null" }, "v": { "type": "boolean" }, "w": { "type": "array", "items": { "type": "string" } } } } } }schemars-0.8.16/tests/expected/schema-openapi3.json000064400000000000000000000667750072674642500204140ustar 00000000000000{ "$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema", "title": "RootSchema", "description": "The root object of a JSON Schema document.", "type": "object", "properties": { "$schema": { "description": "The `$schema` keyword.\n\nSee [JSON Schema 8.1.1. The \"$schema\" Keyword](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.1.1).", "type": "string", "nullable": true }, "definitions": { "description": "The `definitions` keyword.\n\nIn JSON Schema draft 2019-09 this was replaced by $defs, but in Schemars this is still serialized as `definitions` for backward-compatibility.\n\nSee [JSON Schema 8.2.5. Schema Re-Use With \"$defs\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.5), and [JSON Schema (draft 07) 9. Schema Re-Use With \"definitions\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-9).", "type": "object", "additionalProperties": { "$ref": "#/components/schemas/Schema" } }, "type": { "description": "The `type` keyword.\n\nSee [JSON Schema Validation 6.1.1. \"type\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.1) and [JSON Schema 4.2.1. Instance Data Model](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-4.2.1).", "allOf": [ { "$ref": "#/components/schemas/SingleOrVec_for_InstanceType" } ], "nullable": true }, "format": { "description": "The `format` keyword.\n\nSee [JSON Schema Validation 7. A Vocabulary for Semantic Content With \"format\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-7).", "type": "string", "nullable": true }, "enum": { "description": "The `enum` keyword.\n\nSee [JSON Schema Validation 6.1.2. \"enum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.2)", "type": "array", "items": {}, "nullable": true }, "const": { "description": "The `const` keyword.\n\nSee [JSON Schema Validation 6.1.3. \"const\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.3)", "nullable": true }, "$ref": { "description": "The `$ref` keyword.\n\nSee [JSON Schema 8.2.4.1. Direct References with \"$ref\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.4.1).", "type": "string", "nullable": true }, "$id": { "description": "The `$id` keyword.\n\nSee [JSON Schema 8.2.2. The \"$id\" Keyword](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.2).", "type": "string", "nullable": true }, "title": { "description": "The `title` keyword.\n\nSee [JSON Schema Validation 9.1. \"title\" and \"description\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.1).", "type": "string", "nullable": true }, "description": { "description": "The `description` keyword.\n\nSee [JSON Schema Validation 9.1. \"title\" and \"description\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.1).", "type": "string", "nullable": true }, "default": { "description": "The `default` keyword.\n\nSee [JSON Schema Validation 9.2. \"default\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.2).", "nullable": true }, "deprecated": { "description": "The `deprecated` keyword.\n\nSee [JSON Schema Validation 9.3. \"deprecated\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.3).", "type": "boolean" }, "readOnly": { "description": "The `readOnly` keyword.\n\nSee [JSON Schema Validation 9.4. \"readOnly\" and \"writeOnly\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.4).", "type": "boolean" }, "writeOnly": { "description": "The `writeOnly` keyword.\n\nSee [JSON Schema Validation 9.4. \"readOnly\" and \"writeOnly\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.4).", "type": "boolean" }, "examples": { "description": "The `examples` keyword.\n\nSee [JSON Schema Validation 9.5. \"examples\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.5).", "type": "array", "items": {} }, "allOf": { "description": "The `allOf` keyword.\n\nSee [JSON Schema 9.2.1.1. \"allOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.1).", "type": "array", "items": { "$ref": "#/components/schemas/Schema" }, "nullable": true }, "anyOf": { "description": "The `anyOf` keyword.\n\nSee [JSON Schema 9.2.1.2. \"anyOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.2).", "type": "array", "items": { "$ref": "#/components/schemas/Schema" }, "nullable": true }, "oneOf": { "description": "The `oneOf` keyword.\n\nSee [JSON Schema 9.2.1.3. \"oneOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.3).", "type": "array", "items": { "$ref": "#/components/schemas/Schema" }, "nullable": true }, "not": { "description": "The `not` keyword.\n\nSee [JSON Schema 9.2.1.4. \"not\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.4).", "allOf": [ { "$ref": "#/components/schemas/Schema" } ], "nullable": true }, "if": { "description": "The `if` keyword.\n\nSee [JSON Schema 9.2.2.1. \"if\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.1).", "allOf": [ { "$ref": "#/components/schemas/Schema" } ], "nullable": true }, "then": { "description": "The `then` keyword.\n\nSee [JSON Schema 9.2.2.2. \"then\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.2).", "allOf": [ { "$ref": "#/components/schemas/Schema" } ], "nullable": true }, "else": { "description": "The `else` keyword.\n\nSee [JSON Schema 9.2.2.3. \"else\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.3).", "allOf": [ { "$ref": "#/components/schemas/Schema" } ], "nullable": true }, "multipleOf": { "description": "The `multipleOf` keyword.\n\nSee [JSON Schema Validation 6.2.1. \"multipleOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.1).", "type": "number", "format": "double", "nullable": true }, "maximum": { "description": "The `maximum` keyword.\n\nSee [JSON Schema Validation 6.2.2. \"maximum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.2).", "type": "number", "format": "double", "nullable": true }, "exclusiveMaximum": { "description": "The `exclusiveMaximum` keyword.\n\nSee [JSON Schema Validation 6.2.3. \"exclusiveMaximum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.3).", "type": "number", "format": "double", "nullable": true }, "minimum": { "description": "The `minimum` keyword.\n\nSee [JSON Schema Validation 6.2.4. \"minimum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.4).", "type": "number", "format": "double", "nullable": true }, "exclusiveMinimum": { "description": "The `exclusiveMinimum` keyword.\n\nSee [JSON Schema Validation 6.2.5. \"exclusiveMinimum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.5).", "type": "number", "format": "double", "nullable": true }, "maxLength": { "description": "The `maxLength` keyword.\n\nSee [JSON Schema Validation 6.3.1. \"maxLength\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.1).", "type": "integer", "format": "uint32", "minimum": 0.0, "nullable": true }, "minLength": { "description": "The `minLength` keyword.\n\nSee [JSON Schema Validation 6.3.2. \"minLength\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.2).", "type": "integer", "format": "uint32", "minimum": 0.0, "nullable": true }, "pattern": { "description": "The `pattern` keyword.\n\nSee [JSON Schema Validation 6.3.3. \"pattern\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.3).", "type": "string", "nullable": true }, "items": { "description": "The `items` keyword.\n\nSee [JSON Schema 9.3.1.1. \"items\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.1).", "allOf": [ { "$ref": "#/components/schemas/SingleOrVec_for_Schema" } ], "nullable": true }, "additionalItems": { "description": "The `additionalItems` keyword.\n\nSee [JSON Schema 9.3.1.2. \"additionalItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.2).", "allOf": [ { "$ref": "#/components/schemas/Schema" } ], "nullable": true }, "maxItems": { "description": "The `maxItems` keyword.\n\nSee [JSON Schema Validation 6.4.1. \"maxItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.1).", "type": "integer", "format": "uint32", "minimum": 0.0, "nullable": true }, "minItems": { "description": "The `minItems` keyword.\n\nSee [JSON Schema Validation 6.4.2. \"minItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.2).", "type": "integer", "format": "uint32", "minimum": 0.0, "nullable": true }, "uniqueItems": { "description": "The `uniqueItems` keyword.\n\nSee [JSON Schema Validation 6.4.3. \"uniqueItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.3).", "type": "boolean", "nullable": true }, "contains": { "description": "The `contains` keyword.\n\nSee [JSON Schema 9.3.1.4. \"contains\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.4).", "allOf": [ { "$ref": "#/components/schemas/Schema" } ], "nullable": true }, "maxProperties": { "description": "The `maxProperties` keyword.\n\nSee [JSON Schema Validation 6.5.1. \"maxProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.1).", "type": "integer", "format": "uint32", "minimum": 0.0, "nullable": true }, "minProperties": { "description": "The `minProperties` keyword.\n\nSee [JSON Schema Validation 6.5.2. \"minProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.2).", "type": "integer", "format": "uint32", "minimum": 0.0, "nullable": true }, "required": { "description": "The `required` keyword.\n\nSee [JSON Schema Validation 6.5.3. \"required\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.3).", "type": "array", "items": { "type": "string" }, "uniqueItems": true }, "properties": { "description": "The `properties` keyword.\n\nSee [JSON Schema 9.3.2.1. \"properties\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.1).", "type": "object", "additionalProperties": { "$ref": "#/components/schemas/Schema" } }, "patternProperties": { "description": "The `patternProperties` keyword.\n\nSee [JSON Schema 9.3.2.2. \"patternProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.2).", "type": "object", "additionalProperties": { "$ref": "#/components/schemas/Schema" } }, "additionalProperties": { "description": "The `additionalProperties` keyword.\n\nSee [JSON Schema 9.3.2.3. \"additionalProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.3).", "allOf": [ { "$ref": "#/components/schemas/Schema" } ], "nullable": true }, "propertyNames": { "description": "The `propertyNames` keyword.\n\nSee [JSON Schema 9.3.2.5. \"propertyNames\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.5).", "allOf": [ { "$ref": "#/components/schemas/Schema" } ], "nullable": true } }, "additionalProperties": true, "definitions": { "Schema": { "description": "A JSON Schema.", "anyOf": [ { "description": "A trivial boolean JSON Schema.\n\nThe schema `true` matches everything (always passes validation), whereas the schema `false` matches nothing (always fails validation).", "type": "boolean" }, { "description": "A JSON Schema object.", "allOf": [ { "$ref": "#/components/schemas/SchemaObject" } ] } ] }, "SchemaObject": { "description": "A JSON Schema object.", "type": "object", "properties": { "type": { "description": "The `type` keyword.\n\nSee [JSON Schema Validation 6.1.1. \"type\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.1) and [JSON Schema 4.2.1. Instance Data Model](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-4.2.1).", "allOf": [ { "$ref": "#/components/schemas/SingleOrVec_for_InstanceType" } ], "nullable": true }, "format": { "description": "The `format` keyword.\n\nSee [JSON Schema Validation 7. A Vocabulary for Semantic Content With \"format\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-7).", "type": "string", "nullable": true }, "enum": { "description": "The `enum` keyword.\n\nSee [JSON Schema Validation 6.1.2. \"enum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.2)", "type": "array", "items": {}, "nullable": true }, "const": { "description": "The `const` keyword.\n\nSee [JSON Schema Validation 6.1.3. \"const\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.3)", "nullable": true }, "$ref": { "description": "The `$ref` keyword.\n\nSee [JSON Schema 8.2.4.1. Direct References with \"$ref\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.4.1).", "type": "string", "nullable": true }, "$id": { "description": "The `$id` keyword.\n\nSee [JSON Schema 8.2.2. The \"$id\" Keyword](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.2).", "type": "string", "nullable": true }, "title": { "description": "The `title` keyword.\n\nSee [JSON Schema Validation 9.1. \"title\" and \"description\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.1).", "type": "string", "nullable": true }, "description": { "description": "The `description` keyword.\n\nSee [JSON Schema Validation 9.1. \"title\" and \"description\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.1).", "type": "string", "nullable": true }, "default": { "description": "The `default` keyword.\n\nSee [JSON Schema Validation 9.2. \"default\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.2).", "nullable": true }, "deprecated": { "description": "The `deprecated` keyword.\n\nSee [JSON Schema Validation 9.3. \"deprecated\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.3).", "type": "boolean" }, "readOnly": { "description": "The `readOnly` keyword.\n\nSee [JSON Schema Validation 9.4. \"readOnly\" and \"writeOnly\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.4).", "type": "boolean" }, "writeOnly": { "description": "The `writeOnly` keyword.\n\nSee [JSON Schema Validation 9.4. \"readOnly\" and \"writeOnly\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.4).", "type": "boolean" }, "examples": { "description": "The `examples` keyword.\n\nSee [JSON Schema Validation 9.5. \"examples\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.5).", "type": "array", "items": {} }, "allOf": { "description": "The `allOf` keyword.\n\nSee [JSON Schema 9.2.1.1. \"allOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.1).", "type": "array", "items": { "$ref": "#/components/schemas/Schema" }, "nullable": true }, "anyOf": { "description": "The `anyOf` keyword.\n\nSee [JSON Schema 9.2.1.2. \"anyOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.2).", "type": "array", "items": { "$ref": "#/components/schemas/Schema" }, "nullable": true }, "oneOf": { "description": "The `oneOf` keyword.\n\nSee [JSON Schema 9.2.1.3. \"oneOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.3).", "type": "array", "items": { "$ref": "#/components/schemas/Schema" }, "nullable": true }, "not": { "description": "The `not` keyword.\n\nSee [JSON Schema 9.2.1.4. \"not\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.4).", "allOf": [ { "$ref": "#/components/schemas/Schema" } ], "nullable": true }, "if": { "description": "The `if` keyword.\n\nSee [JSON Schema 9.2.2.1. \"if\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.1).", "allOf": [ { "$ref": "#/components/schemas/Schema" } ], "nullable": true }, "then": { "description": "The `then` keyword.\n\nSee [JSON Schema 9.2.2.2. \"then\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.2).", "allOf": [ { "$ref": "#/components/schemas/Schema" } ], "nullable": true }, "else": { "description": "The `else` keyword.\n\nSee [JSON Schema 9.2.2.3. \"else\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.3).", "allOf": [ { "$ref": "#/components/schemas/Schema" } ], "nullable": true }, "multipleOf": { "description": "The `multipleOf` keyword.\n\nSee [JSON Schema Validation 6.2.1. \"multipleOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.1).", "type": "number", "format": "double", "nullable": true }, "maximum": { "description": "The `maximum` keyword.\n\nSee [JSON Schema Validation 6.2.2. \"maximum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.2).", "type": "number", "format": "double", "nullable": true }, "exclusiveMaximum": { "description": "The `exclusiveMaximum` keyword.\n\nSee [JSON Schema Validation 6.2.3. \"exclusiveMaximum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.3).", "type": "number", "format": "double", "nullable": true }, "minimum": { "description": "The `minimum` keyword.\n\nSee [JSON Schema Validation 6.2.4. \"minimum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.4).", "type": "number", "format": "double", "nullable": true }, "exclusiveMinimum": { "description": "The `exclusiveMinimum` keyword.\n\nSee [JSON Schema Validation 6.2.5. \"exclusiveMinimum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.5).", "type": "number", "format": "double", "nullable": true }, "maxLength": { "description": "The `maxLength` keyword.\n\nSee [JSON Schema Validation 6.3.1. \"maxLength\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.1).", "type": "integer", "format": "uint32", "minimum": 0.0, "nullable": true }, "minLength": { "description": "The `minLength` keyword.\n\nSee [JSON Schema Validation 6.3.2. \"minLength\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.2).", "type": "integer", "format": "uint32", "minimum": 0.0, "nullable": true }, "pattern": { "description": "The `pattern` keyword.\n\nSee [JSON Schema Validation 6.3.3. \"pattern\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.3).", "type": "string", "nullable": true }, "items": { "description": "The `items` keyword.\n\nSee [JSON Schema 9.3.1.1. \"items\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.1).", "allOf": [ { "$ref": "#/components/schemas/SingleOrVec_for_Schema" } ], "nullable": true }, "additionalItems": { "description": "The `additionalItems` keyword.\n\nSee [JSON Schema 9.3.1.2. \"additionalItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.2).", "allOf": [ { "$ref": "#/components/schemas/Schema" } ], "nullable": true }, "maxItems": { "description": "The `maxItems` keyword.\n\nSee [JSON Schema Validation 6.4.1. \"maxItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.1).", "type": "integer", "format": "uint32", "minimum": 0.0, "nullable": true }, "minItems": { "description": "The `minItems` keyword.\n\nSee [JSON Schema Validation 6.4.2. \"minItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.2).", "type": "integer", "format": "uint32", "minimum": 0.0, "nullable": true }, "uniqueItems": { "description": "The `uniqueItems` keyword.\n\nSee [JSON Schema Validation 6.4.3. \"uniqueItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.3).", "type": "boolean", "nullable": true }, "contains": { "description": "The `contains` keyword.\n\nSee [JSON Schema 9.3.1.4. \"contains\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.4).", "allOf": [ { "$ref": "#/components/schemas/Schema" } ], "nullable": true }, "maxProperties": { "description": "The `maxProperties` keyword.\n\nSee [JSON Schema Validation 6.5.1. \"maxProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.1).", "type": "integer", "format": "uint32", "minimum": 0.0, "nullable": true }, "minProperties": { "description": "The `minProperties` keyword.\n\nSee [JSON Schema Validation 6.5.2. \"minProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.2).", "type": "integer", "format": "uint32", "minimum": 0.0, "nullable": true }, "required": { "description": "The `required` keyword.\n\nSee [JSON Schema Validation 6.5.3. \"required\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.3).", "type": "array", "items": { "type": "string" }, "uniqueItems": true }, "properties": { "description": "The `properties` keyword.\n\nSee [JSON Schema 9.3.2.1. \"properties\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.1).", "type": "object", "additionalProperties": { "$ref": "#/components/schemas/Schema" } }, "patternProperties": { "description": "The `patternProperties` keyword.\n\nSee [JSON Schema 9.3.2.2. \"patternProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.2).", "type": "object", "additionalProperties": { "$ref": "#/components/schemas/Schema" } }, "additionalProperties": { "description": "The `additionalProperties` keyword.\n\nSee [JSON Schema 9.3.2.3. \"additionalProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.3).", "allOf": [ { "$ref": "#/components/schemas/Schema" } ], "nullable": true }, "propertyNames": { "description": "The `propertyNames` keyword.\n\nSee [JSON Schema 9.3.2.5. \"propertyNames\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.5).", "allOf": [ { "$ref": "#/components/schemas/Schema" } ], "nullable": true } }, "additionalProperties": true }, "SingleOrVec_for_InstanceType": { "description": "A type which can be serialized as a single item, or multiple items.\n\nIn some contexts, a `Single` may be semantically distinct from a `Vec` containing only item.", "anyOf": [ { "$ref": "#/components/schemas/InstanceType" }, { "type": "array", "items": { "$ref": "#/components/schemas/InstanceType" } } ] }, "InstanceType": { "description": "The possible types of values in JSON Schema documents.\n\nSee [JSON Schema 4.2.1. Instance Data Model](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-4.2.1).", "type": "string", "enum": [ "null", "boolean", "object", "array", "number", "string", "integer" ] }, "SingleOrVec_for_Schema": { "description": "A type which can be serialized as a single item, or multiple items.\n\nIn some contexts, a `Single` may be semantically distinct from a `Vec` containing only item.", "anyOf": [ { "$ref": "#/components/schemas/Schema" }, { "type": "array", "items": { "$ref": "#/components/schemas/Schema" } } ] } } }schemars-0.8.16/tests/expected/schema.json000064400000000000000000000703730072674642500166650ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "RootSchema", "description": "The root object of a JSON Schema document.", "type": "object", "properties": { "$schema": { "description": "The `$schema` keyword.\n\nSee [JSON Schema 8.1.1. The \"$schema\" Keyword](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.1.1).", "type": [ "string", "null" ] }, "definitions": { "description": "The `definitions` keyword.\n\nIn JSON Schema draft 2019-09 this was replaced by $defs, but in Schemars this is still serialized as `definitions` for backward-compatibility.\n\nSee [JSON Schema 8.2.5. Schema Re-Use With \"$defs\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.5), and [JSON Schema (draft 07) 9. Schema Re-Use With \"definitions\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-9).", "type": "object", "additionalProperties": { "$ref": "#/definitions/Schema" } }, "type": { "description": "The `type` keyword.\n\nSee [JSON Schema Validation 6.1.1. \"type\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.1) and [JSON Schema 4.2.1. Instance Data Model](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-4.2.1).", "anyOf": [ { "$ref": "#/definitions/SingleOrVec_for_InstanceType" }, { "type": "null" } ] }, "format": { "description": "The `format` keyword.\n\nSee [JSON Schema Validation 7. A Vocabulary for Semantic Content With \"format\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-7).", "type": [ "string", "null" ] }, "enum": { "description": "The `enum` keyword.\n\nSee [JSON Schema Validation 6.1.2. \"enum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.2)", "type": [ "array", "null" ], "items": true }, "const": { "description": "The `const` keyword.\n\nSee [JSON Schema Validation 6.1.3. \"const\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.3)" }, "$ref": { "description": "The `$ref` keyword.\n\nSee [JSON Schema 8.2.4.1. Direct References with \"$ref\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.4.1).", "type": [ "string", "null" ] }, "$id": { "description": "The `$id` keyword.\n\nSee [JSON Schema 8.2.2. The \"$id\" Keyword](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.2).", "type": [ "string", "null" ] }, "title": { "description": "The `title` keyword.\n\nSee [JSON Schema Validation 9.1. \"title\" and \"description\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.1).", "type": [ "string", "null" ] }, "description": { "description": "The `description` keyword.\n\nSee [JSON Schema Validation 9.1. \"title\" and \"description\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.1).", "type": [ "string", "null" ] }, "default": { "description": "The `default` keyword.\n\nSee [JSON Schema Validation 9.2. \"default\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.2)." }, "deprecated": { "description": "The `deprecated` keyword.\n\nSee [JSON Schema Validation 9.3. \"deprecated\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.3).", "type": "boolean" }, "readOnly": { "description": "The `readOnly` keyword.\n\nSee [JSON Schema Validation 9.4. \"readOnly\" and \"writeOnly\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.4).", "type": "boolean" }, "writeOnly": { "description": "The `writeOnly` keyword.\n\nSee [JSON Schema Validation 9.4. \"readOnly\" and \"writeOnly\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.4).", "type": "boolean" }, "examples": { "description": "The `examples` keyword.\n\nSee [JSON Schema Validation 9.5. \"examples\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.5).", "type": "array", "items": true }, "allOf": { "description": "The `allOf` keyword.\n\nSee [JSON Schema 9.2.1.1. \"allOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.1).", "type": [ "array", "null" ], "items": { "$ref": "#/definitions/Schema" } }, "anyOf": { "description": "The `anyOf` keyword.\n\nSee [JSON Schema 9.2.1.2. \"anyOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.2).", "type": [ "array", "null" ], "items": { "$ref": "#/definitions/Schema" } }, "oneOf": { "description": "The `oneOf` keyword.\n\nSee [JSON Schema 9.2.1.3. \"oneOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.3).", "type": [ "array", "null" ], "items": { "$ref": "#/definitions/Schema" } }, "not": { "description": "The `not` keyword.\n\nSee [JSON Schema 9.2.1.4. \"not\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.4).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "if": { "description": "The `if` keyword.\n\nSee [JSON Schema 9.2.2.1. \"if\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.1).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "then": { "description": "The `then` keyword.\n\nSee [JSON Schema 9.2.2.2. \"then\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.2).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "else": { "description": "The `else` keyword.\n\nSee [JSON Schema 9.2.2.3. \"else\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.3).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "multipleOf": { "description": "The `multipleOf` keyword.\n\nSee [JSON Schema Validation 6.2.1. \"multipleOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.1).", "type": [ "number", "null" ], "format": "double" }, "maximum": { "description": "The `maximum` keyword.\n\nSee [JSON Schema Validation 6.2.2. \"maximum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.2).", "type": [ "number", "null" ], "format": "double" }, "exclusiveMaximum": { "description": "The `exclusiveMaximum` keyword.\n\nSee [JSON Schema Validation 6.2.3. \"exclusiveMaximum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.3).", "type": [ "number", "null" ], "format": "double" }, "minimum": { "description": "The `minimum` keyword.\n\nSee [JSON Schema Validation 6.2.4. \"minimum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.4).", "type": [ "number", "null" ], "format": "double" }, "exclusiveMinimum": { "description": "The `exclusiveMinimum` keyword.\n\nSee [JSON Schema Validation 6.2.5. \"exclusiveMinimum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.5).", "type": [ "number", "null" ], "format": "double" }, "maxLength": { "description": "The `maxLength` keyword.\n\nSee [JSON Schema Validation 6.3.1. \"maxLength\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.1).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "minLength": { "description": "The `minLength` keyword.\n\nSee [JSON Schema Validation 6.3.2. \"minLength\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.2).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "pattern": { "description": "The `pattern` keyword.\n\nSee [JSON Schema Validation 6.3.3. \"pattern\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.3).", "type": [ "string", "null" ] }, "items": { "description": "The `items` keyword.\n\nSee [JSON Schema 9.3.1.1. \"items\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.1).", "anyOf": [ { "$ref": "#/definitions/SingleOrVec_for_Schema" }, { "type": "null" } ] }, "additionalItems": { "description": "The `additionalItems` keyword.\n\nSee [JSON Schema 9.3.1.2. \"additionalItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.2).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "maxItems": { "description": "The `maxItems` keyword.\n\nSee [JSON Schema Validation 6.4.1. \"maxItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.1).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "minItems": { "description": "The `minItems` keyword.\n\nSee [JSON Schema Validation 6.4.2. \"minItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.2).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "uniqueItems": { "description": "The `uniqueItems` keyword.\n\nSee [JSON Schema Validation 6.4.3. \"uniqueItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.3).", "type": [ "boolean", "null" ] }, "contains": { "description": "The `contains` keyword.\n\nSee [JSON Schema 9.3.1.4. \"contains\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.4).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "maxProperties": { "description": "The `maxProperties` keyword.\n\nSee [JSON Schema Validation 6.5.1. \"maxProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.1).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "minProperties": { "description": "The `minProperties` keyword.\n\nSee [JSON Schema Validation 6.5.2. \"minProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.2).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "required": { "description": "The `required` keyword.\n\nSee [JSON Schema Validation 6.5.3. \"required\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.3).", "type": "array", "items": { "type": "string" }, "uniqueItems": true }, "properties": { "description": "The `properties` keyword.\n\nSee [JSON Schema 9.3.2.1. \"properties\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.1).", "type": "object", "additionalProperties": { "$ref": "#/definitions/Schema" } }, "patternProperties": { "description": "The `patternProperties` keyword.\n\nSee [JSON Schema 9.3.2.2. \"patternProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.2).", "type": "object", "additionalProperties": { "$ref": "#/definitions/Schema" } }, "additionalProperties": { "description": "The `additionalProperties` keyword.\n\nSee [JSON Schema 9.3.2.3. \"additionalProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.3).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "propertyNames": { "description": "The `propertyNames` keyword.\n\nSee [JSON Schema 9.3.2.5. \"propertyNames\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.5).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] } }, "additionalProperties": true, "definitions": { "Schema": { "description": "A JSON Schema.", "anyOf": [ { "description": "A trivial boolean JSON Schema.\n\nThe schema `true` matches everything (always passes validation), whereas the schema `false` matches nothing (always fails validation).", "type": "boolean" }, { "description": "A JSON Schema object.", "allOf": [ { "$ref": "#/definitions/SchemaObject" } ] } ] }, "SchemaObject": { "description": "A JSON Schema object.", "type": "object", "properties": { "type": { "description": "The `type` keyword.\n\nSee [JSON Schema Validation 6.1.1. \"type\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.1) and [JSON Schema 4.2.1. Instance Data Model](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-4.2.1).", "anyOf": [ { "$ref": "#/definitions/SingleOrVec_for_InstanceType" }, { "type": "null" } ] }, "format": { "description": "The `format` keyword.\n\nSee [JSON Schema Validation 7. A Vocabulary for Semantic Content With \"format\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-7).", "type": [ "string", "null" ] }, "enum": { "description": "The `enum` keyword.\n\nSee [JSON Schema Validation 6.1.2. \"enum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.2)", "type": [ "array", "null" ], "items": true }, "const": { "description": "The `const` keyword.\n\nSee [JSON Schema Validation 6.1.3. \"const\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.3)" }, "$ref": { "description": "The `$ref` keyword.\n\nSee [JSON Schema 8.2.4.1. Direct References with \"$ref\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.4.1).", "type": [ "string", "null" ] }, "$id": { "description": "The `$id` keyword.\n\nSee [JSON Schema 8.2.2. The \"$id\" Keyword](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.2).", "type": [ "string", "null" ] }, "title": { "description": "The `title` keyword.\n\nSee [JSON Schema Validation 9.1. \"title\" and \"description\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.1).", "type": [ "string", "null" ] }, "description": { "description": "The `description` keyword.\n\nSee [JSON Schema Validation 9.1. \"title\" and \"description\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.1).", "type": [ "string", "null" ] }, "default": { "description": "The `default` keyword.\n\nSee [JSON Schema Validation 9.2. \"default\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.2)." }, "deprecated": { "description": "The `deprecated` keyword.\n\nSee [JSON Schema Validation 9.3. \"deprecated\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.3).", "type": "boolean" }, "readOnly": { "description": "The `readOnly` keyword.\n\nSee [JSON Schema Validation 9.4. \"readOnly\" and \"writeOnly\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.4).", "type": "boolean" }, "writeOnly": { "description": "The `writeOnly` keyword.\n\nSee [JSON Schema Validation 9.4. \"readOnly\" and \"writeOnly\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.4).", "type": "boolean" }, "examples": { "description": "The `examples` keyword.\n\nSee [JSON Schema Validation 9.5. \"examples\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.5).", "type": "array", "items": true }, "allOf": { "description": "The `allOf` keyword.\n\nSee [JSON Schema 9.2.1.1. \"allOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.1).", "type": [ "array", "null" ], "items": { "$ref": "#/definitions/Schema" } }, "anyOf": { "description": "The `anyOf` keyword.\n\nSee [JSON Schema 9.2.1.2. \"anyOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.2).", "type": [ "array", "null" ], "items": { "$ref": "#/definitions/Schema" } }, "oneOf": { "description": "The `oneOf` keyword.\n\nSee [JSON Schema 9.2.1.3. \"oneOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.3).", "type": [ "array", "null" ], "items": { "$ref": "#/definitions/Schema" } }, "not": { "description": "The `not` keyword.\n\nSee [JSON Schema 9.2.1.4. \"not\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.4).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "if": { "description": "The `if` keyword.\n\nSee [JSON Schema 9.2.2.1. \"if\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.1).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "then": { "description": "The `then` keyword.\n\nSee [JSON Schema 9.2.2.2. \"then\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.2).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "else": { "description": "The `else` keyword.\n\nSee [JSON Schema 9.2.2.3. \"else\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.3).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "multipleOf": { "description": "The `multipleOf` keyword.\n\nSee [JSON Schema Validation 6.2.1. \"multipleOf\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.1).", "type": [ "number", "null" ], "format": "double" }, "maximum": { "description": "The `maximum` keyword.\n\nSee [JSON Schema Validation 6.2.2. \"maximum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.2).", "type": [ "number", "null" ], "format": "double" }, "exclusiveMaximum": { "description": "The `exclusiveMaximum` keyword.\n\nSee [JSON Schema Validation 6.2.3. \"exclusiveMaximum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.3).", "type": [ "number", "null" ], "format": "double" }, "minimum": { "description": "The `minimum` keyword.\n\nSee [JSON Schema Validation 6.2.4. \"minimum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.4).", "type": [ "number", "null" ], "format": "double" }, "exclusiveMinimum": { "description": "The `exclusiveMinimum` keyword.\n\nSee [JSON Schema Validation 6.2.5. \"exclusiveMinimum\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.5).", "type": [ "number", "null" ], "format": "double" }, "maxLength": { "description": "The `maxLength` keyword.\n\nSee [JSON Schema Validation 6.3.1. \"maxLength\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.1).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "minLength": { "description": "The `minLength` keyword.\n\nSee [JSON Schema Validation 6.3.2. \"minLength\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.2).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "pattern": { "description": "The `pattern` keyword.\n\nSee [JSON Schema Validation 6.3.3. \"pattern\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.3).", "type": [ "string", "null" ] }, "items": { "description": "The `items` keyword.\n\nSee [JSON Schema 9.3.1.1. \"items\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.1).", "anyOf": [ { "$ref": "#/definitions/SingleOrVec_for_Schema" }, { "type": "null" } ] }, "additionalItems": { "description": "The `additionalItems` keyword.\n\nSee [JSON Schema 9.3.1.2. \"additionalItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.2).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "maxItems": { "description": "The `maxItems` keyword.\n\nSee [JSON Schema Validation 6.4.1. \"maxItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.1).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "minItems": { "description": "The `minItems` keyword.\n\nSee [JSON Schema Validation 6.4.2. \"minItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.2).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "uniqueItems": { "description": "The `uniqueItems` keyword.\n\nSee [JSON Schema Validation 6.4.3. \"uniqueItems\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.3).", "type": [ "boolean", "null" ] }, "contains": { "description": "The `contains` keyword.\n\nSee [JSON Schema 9.3.1.4. \"contains\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.4).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "maxProperties": { "description": "The `maxProperties` keyword.\n\nSee [JSON Schema Validation 6.5.1. \"maxProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.1).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "minProperties": { "description": "The `minProperties` keyword.\n\nSee [JSON Schema Validation 6.5.2. \"minProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.2).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0.0 }, "required": { "description": "The `required` keyword.\n\nSee [JSON Schema Validation 6.5.3. \"required\"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.3).", "type": "array", "items": { "type": "string" }, "uniqueItems": true }, "properties": { "description": "The `properties` keyword.\n\nSee [JSON Schema 9.3.2.1. \"properties\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.1).", "type": "object", "additionalProperties": { "$ref": "#/definitions/Schema" } }, "patternProperties": { "description": "The `patternProperties` keyword.\n\nSee [JSON Schema 9.3.2.2. \"patternProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.2).", "type": "object", "additionalProperties": { "$ref": "#/definitions/Schema" } }, "additionalProperties": { "description": "The `additionalProperties` keyword.\n\nSee [JSON Schema 9.3.2.3. \"additionalProperties\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.3).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] }, "propertyNames": { "description": "The `propertyNames` keyword.\n\nSee [JSON Schema 9.3.2.5. \"propertyNames\"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.5).", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "null" } ] } }, "additionalProperties": true }, "SingleOrVec_for_InstanceType": { "description": "A type which can be serialized as a single item, or multiple items.\n\nIn some contexts, a `Single` may be semantically distinct from a `Vec` containing only item.", "anyOf": [ { "$ref": "#/definitions/InstanceType" }, { "type": "array", "items": { "$ref": "#/definitions/InstanceType" } } ] }, "InstanceType": { "description": "The possible types of values in JSON Schema documents.\n\nSee [JSON Schema 4.2.1. Instance Data Model](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-4.2.1).", "type": "string", "enum": [ "null", "boolean", "object", "array", "number", "string", "integer" ] }, "SingleOrVec_for_Schema": { "description": "A type which can be serialized as a single item, or multiple items.\n\nIn some contexts, a `Single` may be semantically distinct from a `Vec` containing only item.", "anyOf": [ { "$ref": "#/definitions/Schema" }, { "type": "array", "items": { "$ref": "#/definitions/Schema" } } ] } } }schemars-0.8.16/tests/expected/schema_with-enum-adjacent-tagged.json000064400000000000000000000031200072674642500236440ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Adjacent", "oneOf": [ { "type": "object", "required": [ "c", "t" ], "properties": { "c": { "type": "object", "required": [ "foo" ], "properties": { "foo": { "type": "boolean" } } }, "t": { "type": "string", "enum": [ "Struct" ] } } }, { "type": "object", "required": [ "c", "t" ], "properties": { "c": { "type": "boolean" }, "t": { "type": "string", "enum": [ "NewType" ] } } }, { "type": "object", "required": [ "c", "t" ], "properties": { "c": { "type": "array", "items": [ { "type": "boolean" }, { "type": "integer", "format": "int32" } ], "maxItems": 2, "minItems": 2 }, "t": { "type": "string", "enum": [ "Tuple" ] } } }, { "type": "object", "required": [ "c", "t" ], "properties": { "c": { "type": "boolean" }, "t": { "type": "string", "enum": [ "Unit" ] } } } ] }schemars-0.8.16/tests/expected/schema_with-enum-external.json000064400000000000000000000024520072674642500224730ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "External", "oneOf": [ { "type": "object", "required": [ "struct" ], "properties": { "struct": { "type": "object", "required": [ "foo" ], "properties": { "foo": { "type": "boolean" } } } }, "additionalProperties": false }, { "type": "object", "required": [ "newType" ], "properties": { "newType": { "type": "boolean" } }, "additionalProperties": false }, { "type": "object", "required": [ "tuple" ], "properties": { "tuple": { "type": "array", "items": [ { "type": "boolean" }, { "type": "integer", "format": "int32" } ], "maxItems": 2, "minItems": 2 } }, "additionalProperties": false }, { "type": "object", "required": [ "unit" ], "properties": { "unit": { "type": "boolean" } }, "additionalProperties": false } ] }schemars-0.8.16/tests/expected/schema_with-enum-internal.json000064400000000000000000000016660072674642500224730ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Internal", "oneOf": [ { "type": "object", "required": [ "foo", "typeProperty" ], "properties": { "foo": { "type": "boolean" }, "typeProperty": { "type": "string", "enum": [ "Struct" ] } } }, { "type": [ "boolean", "object" ], "required": [ "typeProperty" ], "properties": { "typeProperty": { "type": "string", "enum": [ "NewType" ] } } }, { "type": [ "boolean", "object" ], "required": [ "typeProperty" ], "properties": { "typeProperty": { "type": "string", "enum": [ "Unit" ] } } } ] }schemars-0.8.16/tests/expected/schema_with-enum-untagged.json000064400000000000000000000010660072674642500224470ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Untagged", "anyOf": [ { "type": "object", "required": [ "foo" ], "properties": { "foo": { "type": "boolean" } } }, { "type": "boolean" }, { "type": "array", "items": [ { "type": "boolean" }, { "type": "integer", "format": "int32" } ], "maxItems": 2, "minItems": 2 }, { "type": "boolean" } ] }schemars-0.8.16/tests/expected/schema_with-newtype.json000064400000000000000000000001450072674642500213770ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Newtype", "type": "boolean" }schemars-0.8.16/tests/expected/schema_with-struct.json000064400000000000000000000005130072674642500212270ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Struct", "type": "object", "required": [ "bar", "baz", "foo" ], "properties": { "foo": { "type": "boolean" }, "bar": { "type": "integer", "format": "int32" }, "baz": { "type": "boolean" } } }schemars-0.8.16/tests/expected/schema_with-transparent-newtype.json000064400000000000000000000001470072674642500237400ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "schema_fn", "type": "boolean" }schemars-0.8.16/tests/expected/schema_with-tuple.json000064400000000000000000000004340072674642500210360ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Tuple", "type": "array", "items": [ { "type": "boolean" }, { "type": "integer", "format": "int32" }, { "type": "boolean" } ], "maxItems": 3, "minItems": 3 }schemars-0.8.16/tests/expected/semver.json000064400000000000000000000006350072674642500167200ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "SemverTypes", "type": "object", "required": ["version"], "properties": { "version": { "type": "string", "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" } } } schemars-0.8.16/tests/expected/skip_enum_variants.json000064400000000000000000000006430072674642500213170ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyEnum", "oneOf": [ { "type": "string", "enum": [ "Included2" ] }, { "type": "object", "required": [ "Included1" ], "properties": { "Included1": { "type": "number", "format": "float" } }, "additionalProperties": false } ] }schemars-0.8.16/tests/expected/skip_struct_fields.json000064400000000000000000000006340072674642500213160ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MyStruct", "type": "object", "required": [ "included", "writable" ], "properties": { "readable": { "default": "", "readOnly": true, "type": "string" }, "writable": { "writeOnly": true, "type": "number", "format": "float" }, "included": { "type": "null" } } }schemars-0.8.16/tests/expected/skip_tuple_fields.json000064400000000000000000000003710072674642500211210ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "TupleStruct", "type": "array", "items": [ { "type": "number", "format": "float" }, { "type": "null" } ], "maxItems": 2, "minItems": 2 }schemars-0.8.16/tests/expected/smallvec.json000064400000000000000000000002220072674642500172150ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Array_of_String", "type": "array", "items": { "type": "string" } }schemars-0.8.16/tests/expected/smol_str.json000064400000000000000000000001430072674642500172530ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "String", "type": "string" }schemars-0.8.16/tests/expected/struct-newtype.json000064400000000000000000000001720072674642500204300ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Newtype", "type": "integer", "format": "int32" }schemars-0.8.16/tests/expected/struct-normal-additional-properties.json000064400000000000000000000006020072674642500245230ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Struct", "type": "object", "required": [ "bar", "foo" ], "properties": { "foo": { "type": "integer", "format": "int32" }, "bar": { "type": "boolean" }, "baz": { "type": [ "string", "null" ] } }, "additionalProperties": false }schemars-0.8.16/tests/expected/struct-normal.json000064400000000000000000000005410072674642500202250ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Struct", "type": "object", "required": [ "bar", "foo" ], "properties": { "foo": { "type": "integer", "format": "int32" }, "bar": { "type": "boolean" }, "baz": { "type": [ "string", "null" ] } } }schemars-0.8.16/tests/expected/struct-tuple.json000064400000000000000000000004750072674642500200740ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Tuple", "type": "array", "items": [ { "type": "integer", "format": "int32" }, { "type": "boolean" }, { "type": [ "string", "null" ] } ], "maxItems": 3, "minItems": 3 }schemars-0.8.16/tests/expected/struct-unit.json000064400000000000000000000001370072674642500177150ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Unit", "type": "null" }schemars-0.8.16/tests/expected/transparent-struct.json000064400000000000000000000010470072674642500213000ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "OuterStruct", "type": "object", "properties": { "inner": { "anyOf": [ { "$ref": "#/definitions/InnerStruct" }, { "type": "null" } ] } }, "definitions": { "InnerStruct": { "type": "array", "items": [ { "type": "string" }, { "type": "integer", "format": "int32" } ], "maxItems": 2, "minItems": 2 } } }schemars-0.8.16/tests/expected/url.json000064400000000000000000000003350072674642500162160ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "UrlTypes", "type": "object", "required": [ "url" ], "properties": { "url": { "type": "string", "format": "uri" } } } schemars-0.8.16/tests/expected/uuid.json000064400000000000000000000001650072674642500163630ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Uuid", "type": "string", "format": "uuid" }schemars-0.8.16/tests/expected/validate.json000064400000000000000000000036440072674642500172130ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Struct", "type": "object", "required": [ "contains_str1", "contains_str2", "email_address", "homepage", "map_contains", "min_max", "min_max2", "non_empty_str", "non_empty_str2", "pair", "regex_str1", "regex_str2", "regex_str3", "required_option", "tel", "x" ], "properties": { "min_max": { "type": "number", "format": "float", "maximum": 100.0, "minimum": 0.01 }, "min_max2": { "type": "number", "format": "float", "maximum": 1000.0, "minimum": 1.0 }, "regex_str1": { "type": "string", "pattern": "^[Hh]ello\\b" }, "regex_str2": { "type": "string", "pattern": "^[Hh]ello\\b" }, "regex_str3": { "type": "string", "pattern": "^\\d+$" }, "contains_str1": { "type": "string", "pattern": "substring\\.\\.\\." }, "contains_str2": { "type": "string", "pattern": "substring\\.\\.\\." }, "email_address": { "type": "string", "format": "email" }, "tel": { "type": "string", "format": "phone" }, "homepage": { "type": "string", "format": "uri" }, "non_empty_str": { "type": "string", "maxLength": 100, "minLength": 1 }, "non_empty_str2": { "type": "string", "maxLength": 1000, "minLength": 1 }, "pair": { "type": "array", "items": { "type": "integer", "format": "int32" }, "maxItems": 2, "minItems": 2 }, "map_contains": { "type": "object", "required": [ "map_key" ], "additionalProperties": { "type": "null" } }, "required_option": { "type": "boolean" }, "x": { "type": "integer", "format": "int32" } } }schemars-0.8.16/tests/expected/validate_inner.json000064400000000000000000000026410072674642500204020ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Struct", "type": "object", "required": [ "array_str_length", "slice_str_contains", "vec_i32_range", "vec_str_length", "vec_str_length2", "vec_str_regex", "vec_str_url" ], "properties": { "array_str_length": { "type": "array", "items": { "type": "string", "maxLength": 100, "minLength": 5 }, "maxItems": 2, "minItems": 2 }, "slice_str_contains": { "type": "array", "items": { "type": "string", "pattern": "substring\\.\\.\\." } }, "vec_i32_range": { "type": "array", "items": { "type": "integer", "format": "int32", "maximum": 10.0, "minimum": -10.0 } }, "vec_str_length": { "type": "array", "items": { "type": "string", "maxLength": 100, "minLength": 1 } }, "vec_str_length2": { "type": "array", "items": { "type": "string", "maxLength": 100, "minLength": 1 }, "maxItems": 3, "minItems": 1 }, "vec_str_regex": { "type": "array", "items": { "type": "string", "pattern": "^[Hh]ello\\b" } }, "vec_str_url": { "type": "array", "items": { "type": "string", "format": "uri" } } } }schemars-0.8.16/tests/expected/validate_newtype.json000064400000000000000000000002370072674642500207610ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "NewType", "type": "integer", "format": "uint8", "maximum": 10.0, "minimum": 0.0 }schemars-0.8.16/tests/expected/validate_schemars_attrs.json000064400000000000000000000036450072674642500223160ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Struct2", "type": "object", "required": [ "contains_str1", "contains_str2", "email_address", "homepage", "map_contains", "min_max", "min_max2", "non_empty_str", "non_empty_str2", "pair", "regex_str1", "regex_str2", "regex_str3", "required_option", "tel", "x" ], "properties": { "min_max": { "type": "number", "format": "float", "maximum": 100.0, "minimum": 0.01 }, "min_max2": { "type": "number", "format": "float", "maximum": 1000.0, "minimum": 1.0 }, "regex_str1": { "type": "string", "pattern": "^[Hh]ello\\b" }, "regex_str2": { "type": "string", "pattern": "^[Hh]ello\\b" }, "regex_str3": { "type": "string", "pattern": "^\\d+$" }, "contains_str1": { "type": "string", "pattern": "substring\\.\\.\\." }, "contains_str2": { "type": "string", "pattern": "substring\\.\\.\\." }, "email_address": { "type": "string", "format": "email" }, "tel": { "type": "string", "format": "phone" }, "homepage": { "type": "string", "format": "uri" }, "non_empty_str": { "type": "string", "maxLength": 100, "minLength": 1 }, "non_empty_str2": { "type": "string", "maxLength": 1000, "minLength": 1 }, "pair": { "type": "array", "items": { "type": "integer", "format": "int32" }, "maxItems": 2, "minItems": 2 }, "map_contains": { "type": "object", "required": [ "map_key" ], "additionalProperties": { "type": "null" } }, "required_option": { "type": "boolean" }, "x": { "type": "integer", "format": "int32" } } }schemars-0.8.16/tests/expected/validate_tuple.json000064400000000000000000000004440072674642500204170ustar 00000000000000{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Tuple", "type": "array", "items": [ { "type": "integer", "format": "uint8", "maximum": 10.0, "minimum": 0.0 }, { "type": "boolean" } ], "maxItems": 2, "minItems": 2 }schemars-0.8.16/tests/ffi.rs000064400000000000000000000004550072674642500140350ustar 00000000000000mod util; use schemars::JsonSchema; use std::ffi::{OsStr, OsString}; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] struct OsStrings { owned: OsString, borrowed: &'static OsStr, } #[test] fn os_strings() -> TestResult { test_default_generated_schema::("os_strings") } schemars-0.8.16/tests/flatten.rs000064400000000000000000000017010072674642500147210ustar 00000000000000mod util; use schemars::JsonSchema; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] struct Flat { f: f32, b: bool, s: String, #[serde(default)] os: String, v: Vec, } #[allow(dead_code)] #[derive(JsonSchema)] #[schemars(rename = "Flat")] struct Deep1 { f: f32, #[schemars(flatten)] deep2: Deep2, v: Vec, } #[allow(clippy::option_option, dead_code)] #[derive(JsonSchema)] struct Deep2 { b: bool, #[serde(flatten)] deep3: Deep3, #[serde(flatten)] deep4: Box>>>, } #[allow(dead_code)] #[derive(JsonSchema)] struct Deep3 { s: &'static str, } #[allow(dead_code)] #[derive(JsonSchema)] struct Deep4 { #[serde(default)] os: &'static str, } #[test] fn test_flat_schema() -> TestResult { test_default_generated_schema::("flatten") } #[test] fn test_flattened_schema() -> TestResult { test_default_generated_schema::("flatten") } schemars-0.8.16/tests/from_value.rs000064400000000000000000000046420072674642500154320ustar 00000000000000mod util; use schemars::gen::{SchemaGenerator, SchemaSettings}; use serde::Serialize; use std::collections::HashMap; use util::*; #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct MyStruct { pub my_int: i32, pub my_bool: bool, pub my_nullable_enum: Option, pub my_inner_struct: MyInnerStruct, #[serde(skip)] pub skip: i32, #[serde(skip_serializing_if = "Option::is_none")] pub skip_if_none: Option, } #[derive(Serialize)] pub struct MyInnerStruct { pub my_map: HashMap, pub my_vec: Vec<&'static str>, pub my_empty_map: HashMap, pub my_empty_vec: Vec<&'static str>, pub my_tuple: (char, u8), } #[derive(Serialize)] pub enum MyEnum { StringNewType(String), StructVariant { floats: Vec }, } fn make_value() -> MyStruct { let mut value = MyStruct { my_int: 123, my_bool: true, my_nullable_enum: None, my_inner_struct: MyInnerStruct { my_map: HashMap::new(), my_vec: vec!["hello", "world"], my_empty_map: HashMap::new(), my_empty_vec: vec![], my_tuple: ('💩', 42), }, skip: 123, skip_if_none: None, }; value.my_inner_struct.my_map.insert(String::new(), 0.0); value } #[test] fn schema_from_value_matches_draft07() -> TestResult { let gen = SchemaSettings::draft07().into_generator(); let actual = gen.into_root_schema_for_value(&make_value())?; test_schema(&actual, "from_value_draft07") } #[test] fn schema_from_value_matches_2019_09() -> TestResult { let gen = SchemaSettings::draft2019_09().into_generator(); let actual = gen.into_root_schema_for_value(&make_value())?; test_schema(&actual, "from_value_2019_09") } #[test] fn schema_from_value_matches_openapi3() -> TestResult { let gen = SchemaSettings::openapi3().into_generator(); let actual = gen.into_root_schema_for_value(&make_value())?; test_schema(&actual, "from_value_openapi3") } #[test] fn schema_from_json_value() -> TestResult { let gen = SchemaGenerator::default(); let actual = gen.into_root_schema_for_value(&serde_json::json!({ "zero": 0, "one": 1, "minusOne": -1, "zeroPointZero": 0.0, "bool": true, "null": null, "object": { "array": ["foo", "bar"] }, }))?; test_schema(&actual, "from_json_value") } schemars-0.8.16/tests/indexmap.rs000064400000000000000000000004770072674642500151020ustar 00000000000000mod util; use indexmap::{IndexMap, IndexSet}; use schemars::JsonSchema; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] struct IndexMapTypes { map: IndexMap, set: IndexSet, } #[test] fn indexmap_types() -> TestResult { test_default_generated_schema::("indexmap") } schemars-0.8.16/tests/indexmap2.rs000064400000000000000000000005000072674642500151470ustar 00000000000000mod util; use indexmap2::{IndexMap, IndexSet}; use schemars::JsonSchema; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] struct IndexMapTypes { map: IndexMap, set: IndexSet, } #[test] fn indexmap_types() -> TestResult { test_default_generated_schema::("indexmap") } schemars-0.8.16/tests/inline_subschemas.rs000064400000000000000000000016350072674642500167650ustar 00000000000000mod util; use schemars::gen::SchemaSettings; use schemars::JsonSchema; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] struct MyJob { spec: MyJobSpec, } #[allow(dead_code)] #[derive(JsonSchema)] struct MyJobSpec { replicas: u32, } #[test] fn struct_normal() -> TestResult { let mut settings = SchemaSettings::default(); settings.inline_subschemas = true; test_generated_schema::("inline-subschemas", settings) } #[allow(dead_code)] #[derive(JsonSchema)] struct RecursiveOuter { direct: Option>, indirect: Option>, } #[allow(dead_code)] #[derive(JsonSchema)] struct RecursiveInner { recursive: RecursiveOuter, } #[test] fn struct_recursive() -> TestResult { let mut settings = SchemaSettings::default(); settings.inline_subschemas = true; test_generated_schema::("inline-subschemas-recursive", settings) } schemars-0.8.16/tests/macro.rs000064400000000000000000000024430072674642500143710ustar 00000000000000mod util; use schemars::JsonSchema; use util::*; macro_rules! build_struct { ( $id:ident { $($t:tt)* } ) => { #[allow(dead_code)] #[derive(JsonSchema)] pub struct $id { x: u8, $($t)* } }; } build_struct!(A { v: i32 }); #[test] fn macro_built_struct() -> TestResult { test_default_generated_schema::("macro_built_struct") } macro_rules! build_enum { ( $(#[$outer_derive:meta])* $outer:ident { $($(#[$inner_derive:meta])* $inner:ident { $( $(#[$field_attribute:meta])* $field:ident : $ty:ty),* })* } ) => { $( $(#[$inner_derive])* pub struct $inner { $( $(#[$field_attribute])* pub $field: $ty ),* } )* $(#[$outer_derive])* pub enum $outer { $( $inner($inner) ),* } } } build_enum!( #[derive(JsonSchema)] OuterEnum { #[derive(JsonSchema)] InnerStruct { x: i32 } } ); #[test] fn macro_built_enum() -> TestResult { test_default_generated_schema::("macro_built_enum") } schemars-0.8.16/tests/nonzero_ints.rs000064400000000000000000000005250072674642500160160ustar 00000000000000mod util; use schemars::JsonSchema; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] struct MyStruct { unsigned: u32, nonzero_unsigned: std::num::NonZeroU32, signed: i32, nonzero_signed: std::num::NonZeroI32, } #[test] fn nonzero_ints() -> TestResult { test_default_generated_schema::("nonzero_ints") } schemars-0.8.16/tests/property_name.rs000064400000000000000000000006760072674642500161620ustar 00000000000000mod util; use schemars::JsonSchema; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] #[serde(rename_all = "camelCase")] struct MyStruct { camel_case: i32, #[serde(rename = "new_name_1")] old_name_1: i32, #[serde(rename = "ignored")] #[schemars(rename = "new_name_2")] old_name_2: i32, } #[test] fn set_struct_property_names() -> TestResult { test_default_generated_schema::("property-name-struct") } schemars-0.8.16/tests/range.rs000064400000000000000000000005230072674642500143610ustar 00000000000000mod util; use schemars::JsonSchema; use std::ops::{Bound, Range, RangeInclusive}; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] struct MyStruct { range: Range, inclusive: RangeInclusive, bound: Bound, } #[test] fn result() -> TestResult { test_default_generated_schema::("range") } schemars-0.8.16/tests/remote_derive.rs000064400000000000000000000017320072674642500161210ustar 00000000000000mod util; use other_crate::Duration; use schemars::JsonSchema; use serde::Serialize; use util::*; mod other_crate { #[derive(Default)] pub struct Duration { pub secs: i64, pub nanos: i32, } } #[derive(JsonSchema, Serialize)] #[serde(remote = "Duration")] struct DurationDef { secs: i64, nanos: i32, } fn custom_serialize(value: &Duration, ser: S) -> Result where S: serde::Serializer, { ser.collect_str(&format_args!("{}.{:09}s", value.secs, value.nanos)) } #[derive(JsonSchema, Serialize)] struct Process { command_line: String, #[serde(with = "DurationDef")] wall_time: Duration, #[serde(default, with = "DurationDef")] user_cpu_time: Duration, #[serde(default, serialize_with = "custom_serialize")] #[schemars(with = "DurationDef")] system_cpu_time: Duration, } #[test] fn remote_derive_json_schema() -> TestResult { test_default_generated_schema::("remote_derive") } schemars-0.8.16/tests/remote_derive_generic.rs000064400000000000000000000021410072674642500176100ustar 00000000000000mod util; use schemars::JsonSchema; use serde::Serialize; use std::collections::{HashMap, HashSet}; use util::*; #[allow(dead_code)] enum Or { A(A), B(B), } #[derive(JsonSchema, Serialize)] #[serde(untagged, remote = "Or")] enum OrDef { A(A), B(B), } struct Str<'a>(&'a str); #[derive(JsonSchema, Serialize)] #[serde(remote = "Str")] struct StrDef<'a>(&'a str); #[derive(JsonSchema, Serialize)] struct MyStruct<'a, T: Serialize> { // #[serde(with = "OrDef::<_, _>")] // byte_or_bool1: Or, #[serde(with = "OrDef::")] byte_or_bool2: Or, // #[serde(with = "OrDef::<_, _>")] // unit_or_t1: Or<(), T>, #[serde(with = "OrDef::<(), T>")] unit_or_t2: Or<(), T>, #[serde(borrow, with = "StrDef")] s: Str<'a>, // #[schemars(with = "HashMap::<_, HashSet<_>>")] // map: BTreeMap>, #[schemars(with = "HashMap::>")] fake_map: (), } #[test] fn remote_derive_json_schema() -> TestResult { test_default_generated_schema::>("remote_derive_generic") } schemars-0.8.16/tests/result.rs000064400000000000000000000005510072674642500146040ustar 00000000000000mod util; use schemars::JsonSchema; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] struct MyStruct { foo: i32, } #[allow(dead_code)] #[derive(JsonSchema)] struct Container { result1: Result>, result2: Result, } #[test] fn result() -> TestResult { test_default_generated_schema::("result") } schemars-0.8.16/tests/same_name.rs000064400000000000000000000010140072674642500152060ustar 00000000000000mod util; use schemars::JsonSchema; use util::*; mod a { use super::*; #[allow(dead_code)] #[derive(JsonSchema)] pub struct Config { test: String, } } mod b { use super::*; #[allow(dead_code)] #[derive(JsonSchema)] pub struct Config { test2: String, } } #[allow(dead_code)] #[derive(JsonSchema)] pub struct Config2 { a_cfg: a::Config, b_cfg: b::Config, } #[test] fn same_name() -> TestResult { test_default_generated_schema::("same_name") } schemars-0.8.16/tests/schema_for_schema.rs000064400000000000000000000010000072674642500167020ustar 00000000000000mod util; use schemars::gen::SchemaSettings; use schemars::schema::RootSchema; use util::*; #[test] fn schema_matches_draft07() -> TestResult { test_generated_schema::("schema", SchemaSettings::draft07()) } #[test] fn schema_matches_2019_09() -> TestResult { test_generated_schema::("schema-2019_09", SchemaSettings::draft2019_09()) } #[test] fn schema_matches_openapi3() -> TestResult { test_generated_schema::("schema-openapi3", SchemaSettings::openapi3()) } schemars-0.8.16/tests/schema_name.rs000064400000000000000000000032770072674642500155360ustar 00000000000000mod util; use schemars::JsonSchema; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] struct MyStruct { t: T, u: U, v: V, w: W, inner: MySimpleStruct, } #[allow(dead_code)] #[derive(JsonSchema)] struct MySimpleStruct { foo: i32, } #[test] fn default_name_multiple_type_params() -> TestResult { test_default_generated_schema::>>("schema-name-default") } #[allow(dead_code)] #[derive(JsonSchema)] #[serde(rename = "a-new-name-{W}-{T}-{T}")] #[schemars(rename_all = "camelCase")] struct MyRenamedStruct { t: T, u: U, v: V, w: W, inner: MySimpleRenamedStruct, } #[allow(dead_code)] #[derive(JsonSchema)] #[serde(rename = "this-attribute-is-ignored")] #[schemars(rename = "another-new-name")] struct MySimpleRenamedStruct { foo: i32, } #[test] fn overriden_with_rename_multiple_type_params() -> TestResult { test_default_generated_schema::>>( "schema-name-custom", ) } #[allow(dead_code)] #[derive(JsonSchema)] #[schemars(rename = "const-generics-{BAR}-")] struct ConstGenericStruct { foo: i32, } #[test] fn overriden_with_rename_const_generics() -> TestResult { test_default_generated_schema::>("schema-name-const-generics") } #[allow(dead_code)] #[derive(JsonSchema)] struct MixedGenericStruct { generic: T, foo: i32, } #[test] fn default_name_mixed_generics() -> TestResult { test_default_generated_schema::>, 42, 'z'>>( "schema-name-mixed-generics", ) } schemars-0.8.16/tests/schema_with_enum.rs000064400000000000000000000044070072674642500166110ustar 00000000000000mod util; use schemars::JsonSchema; use util::*; fn schema_fn(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { ::json_schema(gen) } #[derive(Debug)] pub struct DoesntImplementJsonSchema; #[derive(JsonSchema)] #[schemars(rename_all = "camelCase")] pub enum External { Struct { #[schemars(schema_with = "schema_fn")] foo: DoesntImplementJsonSchema, }, NewType(#[schemars(schema_with = "schema_fn")] DoesntImplementJsonSchema), Tuple( #[schemars(schema_with = "schema_fn")] DoesntImplementJsonSchema, i32, ), #[schemars(schema_with = "schema_fn")] Unit, } #[test] fn enum_external_tag() -> TestResult { test_default_generated_schema::("schema_with-enum-external") } #[derive(JsonSchema)] #[schemars(tag = "typeProperty")] pub enum Internal { Struct { #[schemars(schema_with = "schema_fn")] foo: DoesntImplementJsonSchema, }, NewType(#[schemars(schema_with = "schema_fn")] DoesntImplementJsonSchema), #[schemars(schema_with = "schema_fn")] Unit, } #[test] fn enum_internal_tag() -> TestResult { test_default_generated_schema::("schema_with-enum-internal") } #[derive(JsonSchema)] #[schemars(untagged)] pub enum Untagged { Struct { #[schemars(schema_with = "schema_fn")] foo: DoesntImplementJsonSchema, }, NewType(#[schemars(schema_with = "schema_fn")] DoesntImplementJsonSchema), Tuple( #[schemars(schema_with = "schema_fn")] DoesntImplementJsonSchema, i32, ), #[schemars(schema_with = "schema_fn")] Unit, } #[test] fn enum_untagged() -> TestResult { test_default_generated_schema::("schema_with-enum-untagged") } #[derive(JsonSchema)] #[schemars(tag = "t", content = "c")] pub enum Adjacent { Struct { #[schemars(schema_with = "schema_fn")] foo: DoesntImplementJsonSchema, }, NewType(#[schemars(schema_with = "schema_fn")] DoesntImplementJsonSchema), Tuple( #[schemars(schema_with = "schema_fn")] DoesntImplementJsonSchema, i32, ), #[schemars(schema_with = "schema_fn")] Unit, } #[test] fn enum_adjacent_tagged() -> TestResult { test_default_generated_schema::("schema_with-enum-adjacent-tagged") } schemars-0.8.16/tests/schema_with_struct.rs000064400000000000000000000025270072674642500171720ustar 00000000000000mod util; use schemars::JsonSchema; use util::*; fn schema_fn(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { ::json_schema(gen) } struct DoesntImplementJsonSchema; #[allow(dead_code)] #[derive(JsonSchema)] struct Struct { #[schemars(schema_with = "schema_fn")] foo: DoesntImplementJsonSchema, bar: i32, #[schemars(schema_with = "schema_fn")] baz: DoesntImplementJsonSchema, } #[test] fn struct_normal() -> TestResult { test_default_generated_schema::("schema_with-struct") } #[derive(JsonSchema)] pub struct Tuple( #[schemars(schema_with = "schema_fn")] DoesntImplementJsonSchema, i32, #[schemars(schema_with = "schema_fn")] DoesntImplementJsonSchema, ); #[test] fn struct_tuple() -> TestResult { test_default_generated_schema::("schema_with-tuple") } #[derive(JsonSchema)] pub struct Newtype(#[schemars(schema_with = "schema_fn")] DoesntImplementJsonSchema); #[test] fn struct_newtype() -> TestResult { test_default_generated_schema::("schema_with-newtype") } #[derive(JsonSchema)] #[schemars(transparent)] pub struct TransparentNewtype(#[schemars(schema_with = "schema_fn")] DoesntImplementJsonSchema); #[test] fn struct_transparent_newtype() -> TestResult { test_default_generated_schema::("schema_with-transparent-newtype") } schemars-0.8.16/tests/semver.rs000064400000000000000000000004060072674642500145660ustar 00000000000000mod util; use schemars::JsonSchema; use semver::Version; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] struct SemverTypes { version: Version, } #[test] fn semver_types() -> TestResult { test_default_generated_schema::("semver") } schemars-0.8.16/tests/skip.rs000064400000000000000000000020740072674642500142360ustar 00000000000000mod util; use schemars::JsonSchema; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] struct MyStruct { #[schemars(skip)] skipped1: i32, #[serde(skip)] skipped2: bool, #[serde(skip_deserializing)] readable: String, #[serde(skip_serializing)] writable: f32, included: (), } #[test] fn skip_struct_fields() -> TestResult { test_default_generated_schema::("skip_struct_fields") } #[derive(JsonSchema)] struct TupleStruct( #[schemars(skip)] i32, #[serde(skip)] bool, #[serde(skip_deserializing)] String, #[serde(skip_serializing)] f32, (), ); #[test] fn skip_tuple_fields() -> TestResult { test_default_generated_schema::("skip_tuple_fields") } #[derive(JsonSchema)] pub enum MyEnum { #[schemars(skip)] Skipped1(i32), #[serde(skip)] Skipped2, #[serde(skip_deserializing)] Skipped3, #[serde(skip_serializing)] Included1(f32), Included2, } #[test] fn skip_enum_variants() -> TestResult { test_default_generated_schema::("skip_enum_variants") } schemars-0.8.16/tests/smallvec.rs000064400000000000000000000002370072674642500150750ustar 00000000000000mod util; use smallvec::SmallVec; use util::*; #[test] fn smallvec() -> TestResult { test_default_generated_schema::>("smallvec") } schemars-0.8.16/tests/smol_str.rs000064400000000000000000000002200072674642500151210ustar 00000000000000mod util; use smol_str::SmolStr; use util::*; #[test] fn smol_str() -> TestResult { test_default_generated_schema::("smol_str") } schemars-0.8.16/tests/struct.rs000064400000000000000000000015170072674642500146150ustar 00000000000000mod util; use schemars::JsonSchema; use util::*; // Ensure that schemars_derive uses the full path to std::string::String pub struct String; #[allow(dead_code)] #[derive(JsonSchema)] struct Struct { foo: i32, bar: bool, baz: Option<&'static str>, } #[test] fn struct_normal() -> TestResult { test_default_generated_schema::("struct-normal") } #[derive(JsonSchema)] pub struct Tuple(i32, bool, Option<&'static str>); #[test] fn struct_tuple() -> TestResult { test_default_generated_schema::("struct-tuple") } #[derive(JsonSchema)] pub struct Newtype(i32); #[test] fn struct_newtype() -> TestResult { test_default_generated_schema::("struct-newtype") } #[derive(JsonSchema)] pub struct Unit; #[test] fn struct_unit() -> TestResult { test_default_generated_schema::("struct-unit") } schemars-0.8.16/tests/struct_additional_properties.rs000064400000000000000000000005350072674642500212600ustar 00000000000000mod util; use schemars::JsonSchema; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] #[serde(deny_unknown_fields)] pub struct Struct { foo: i32, bar: bool, baz: Option, } #[test] fn struct_normal_additional_properties() -> TestResult { test_default_generated_schema::("struct-normal-additional-properties") } schemars-0.8.16/tests/time.rs000064400000000000000000000005060072674642500142240ustar 00000000000000mod util; use schemars::JsonSchema; use std::time::{Duration, SystemTime}; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] struct MyStruct { duration: Duration, time: SystemTime, } #[test] fn duration_and_systemtime() -> TestResult { test_default_generated_schema::("duration_and_systemtime") } schemars-0.8.16/tests/transparent.rs000064400000000000000000000011120072674642500156210ustar 00000000000000mod util; use schemars::JsonSchema; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] pub struct OuterStruct { inner: TransparentStruct, } #[allow(dead_code)] #[derive(JsonSchema)] #[serde(transparent)] pub struct TransparentStruct { #[serde(with = "TransparentNewType")] inner: (), } #[derive(JsonSchema)] #[schemars(transparent)] pub struct TransparentNewType(Option); #[derive(JsonSchema)] pub struct InnerStruct(String, i32); #[test] fn transparent_struct() -> TestResult { test_default_generated_schema::("transparent-struct") } schemars-0.8.16/tests/ui/invalid_attrs.rs000064400000000000000000000004130072674642500165430ustar 00000000000000use schemars::JsonSchema; #[derive(JsonSchema)] #[serde(default = 0, foo, deny_unknown_fields, deny_unknown_fields)] pub struct Struct1; #[derive(JsonSchema)] #[schemars(default = 0, foo, deny_unknown_fields, deny_unknown_fields)] pub struct Struct2; fn main() {} schemars-0.8.16/tests/ui/invalid_attrs.stderr000064400000000000000000000020740072674642500174270ustar 00000000000000error: expected serde default attribute to be a string: `default = "..."` --> $DIR/invalid_attrs.rs:4:19 | 4 | #[serde(default = 0, foo, deny_unknown_fields, deny_unknown_fields)] | ^ error: duplicate serde attribute `deny_unknown_fields` --> $DIR/invalid_attrs.rs:4:48 | 4 | #[serde(default = 0, foo, deny_unknown_fields, deny_unknown_fields)] | ^^^^^^^^^^^^^^^^^^^ error: expected serde default attribute to be a string: `default = "..."` --> $DIR/invalid_attrs.rs:8:22 | 8 | #[schemars(default = 0, foo, deny_unknown_fields, deny_unknown_fields)] | ^ error: duplicate serde attribute `deny_unknown_fields` --> $DIR/invalid_attrs.rs:8:51 | 8 | #[schemars(default = 0, foo, deny_unknown_fields, deny_unknown_fields)] | ^^^^^^^^^^^^^^^^^^^ error: unknown schemars attribute `foo` --> $DIR/invalid_attrs.rs:8:25 | 8 | #[schemars(default = 0, foo, deny_unknown_fields, deny_unknown_fields)] | ^^^ schemars-0.8.16/tests/ui/invalid_validation_attrs.rs000064400000000000000000000012320072674642500207550ustar 00000000000000use schemars::JsonSchema; #[derive(JsonSchema)] pub struct Struct1(#[validate(regex = 0, foo, length(min = 1, equal = 2, bar))] String); #[derive(JsonSchema)] pub struct Struct2(#[schemars(regex = 0, foo, length(min = 1, equal = 2, bar))] String); #[derive(JsonSchema)] pub struct Struct3( #[validate( regex = "foo", contains = "bar", regex(path = "baz"), phone, email, url )] String, ); #[derive(JsonSchema)] pub struct Struct4( #[schemars( regex = "foo", contains = "bar", regex(path = "baz"), phone, email, url )] String, ); fn main() {} schemars-0.8.16/tests/ui/invalid_validation_attrs.stderr000064400000000000000000000040610072674642500216370ustar 00000000000000error: expected validate regex attribute to be a string: `regex = "..."` --> $DIR/invalid_validation_attrs.rs:4:39 | 4 | pub struct Struct1(#[validate(regex = 0, foo, length(min = 1, equal = 2, bar))] String); | ^ error: unknown schemars attribute `foo` --> $DIR/invalid_validation_attrs.rs:7:42 | 7 | pub struct Struct2(#[schemars(regex = 0, foo, length(min = 1, equal = 2, bar))] String); | ^^^ error: expected schemars regex attribute to be a string: `regex = "..."` --> $DIR/invalid_validation_attrs.rs:7:39 | 7 | pub struct Struct2(#[schemars(regex = 0, foo, length(min = 1, equal = 2, bar))] String); | ^ error: schemars attribute cannot contain both `equal` and `min` --> $DIR/invalid_validation_attrs.rs:7:63 | 7 | pub struct Struct2(#[schemars(regex = 0, foo, length(min = 1, equal = 2, bar))] String); | ^^^^^ error: unknown item in schemars length attribute --> $DIR/invalid_validation_attrs.rs:7:74 | 7 | pub struct Struct2(#[schemars(regex = 0, foo, length(min = 1, equal = 2, bar))] String); | ^^^ error: schemars attribute cannot contain both `contains` and `regex` --> $DIR/invalid_validation_attrs.rs:26:9 | 26 | contains = "bar", | ^^^^^^^^ error: duplicate schemars attribute `regex` --> $DIR/invalid_validation_attrs.rs:27:9 | 27 | regex(path = "baz"), | ^^^^^ error: schemars attribute cannot contain both `phone` and `email` --> $DIR/invalid_validation_attrs.rs:29:9 | 29 | email, | ^^^^^ error: schemars attribute cannot contain both `phone` and `url` --> $DIR/invalid_validation_attrs.rs:30:9 | 30 | url | ^^^ error[E0425]: cannot find value `foo` in this scope --> $DIR/invalid_validation_attrs.rs:12:17 | 12 | regex = "foo", | ^^^^^ not found in this scope schemars-0.8.16/tests/ui/repr_missing.rs000064400000000000000000000001450072674642500164030ustar 00000000000000use schemars::JsonSchema_repr; #[derive(JsonSchema_repr)] pub enum Enum { Unit, } fn main() {} schemars-0.8.16/tests/ui/repr_missing.stderr000064400000000000000000000004370072674642500172660ustar 00000000000000error: JsonSchema_repr: missing #[repr(...)] attribute --> $DIR/repr_missing.rs:3:10 | 3 | #[derive(JsonSchema_repr)] | ^^^^^^^^^^^^^^^ | = note: this error originates in the derive macro `JsonSchema_repr` (in Nightly builds, run with -Z macro-backtrace for more info) schemars-0.8.16/tests/ui/repr_non_unit_variant.rs000064400000000000000000000002030072674642500203020ustar 00000000000000use schemars::JsonSchema_repr; #[derive(JsonSchema_repr)] #[repr(u8)] pub enum Enum { Unit, EmptyTuple(), } fn main() {} schemars-0.8.16/tests/ui/repr_non_unit_variant.stderr000064400000000000000000000002030072674642500211610ustar 00000000000000error: JsonSchema_repr: must be a unit variant --> $DIR/repr_non_unit_variant.rs:7:5 | 7 | EmptyTuple(), | ^^^^^^^^^^ schemars-0.8.16/tests/ui/schema_for_arg_value.rs000064400000000000000000000001150072674642500200320ustar 00000000000000use schemars::schema_for; fn main() { let _schema = schema_for!(123); } schemars-0.8.16/tests/ui/schema_for_arg_value.stderr000064400000000000000000000005360072674642500207200ustar 00000000000000error: This argument to `schema_for!` is not a type - did you mean to use `schema_for_value!` instead? --> $DIR/schema_for_arg_value.rs:4:19 | 4 | let _schema = schema_for!(123); | ^^^^^^^^^^^^^^^^ | = note: this error originates in the macro `schema_for` (in Nightly builds, run with -Z macro-backtrace for more info) schemars-0.8.16/tests/ui.rs000064400000000000000000000001410072674642500136760ustar 00000000000000#[test] fn ui() { let t = trybuild::TestCases::new(); t.compile_fail("tests/ui/*.rs"); } schemars-0.8.16/tests/url.rs000064400000000000000000000003530072674642500140700ustar 00000000000000mod util; use schemars::JsonSchema; use url::Url; use util::*; #[allow(dead_code)] #[derive(JsonSchema)] struct UrlTypes { url: Url, } #[test] fn url_types() -> TestResult { test_default_generated_schema::("url") } schemars-0.8.16/tests/util/mod.rs000064400000000000000000000025720072674642500150270ustar 00000000000000use pretty_assertions::assert_eq; use schemars::{gen::SchemaSettings, schema::RootSchema, schema_for, JsonSchema}; use std::error::Error; use std::fs; pub type TestResult = Result<(), Box>; #[allow(dead_code)] // https://github.com/rust-lang/rust/issues/46379 pub fn test_generated_schema(file: &str, settings: SchemaSettings) -> TestResult { let actual = settings.into_generator().into_root_schema_for::(); test_schema(&actual, file) } #[allow(dead_code)] // https://github.com/rust-lang/rust/issues/46379 pub fn test_default_generated_schema(file: &str) -> TestResult { let actual = schema_for!(T); test_schema(&actual, file) } pub fn test_schema(actual: &RootSchema, file: &str) -> TestResult { let expected_json = match fs::read_to_string(format!("tests/expected/{}.json", file)) { Ok(j) => j, Err(e) => { write_actual_to_file(actual, file)?; return Err(Box::from(e)); } }; let expected = &serde_json::from_str(&expected_json)?; if actual != expected { write_actual_to_file(actual, file)?; } assert_eq!(expected, actual); Ok(()) } fn write_actual_to_file(schema: &RootSchema, file: &str) -> TestResult { let actual_json = serde_json::to_string_pretty(&schema)?; fs::write(format!("tests/actual/{}.json", file), actual_json)?; Ok(()) } schemars-0.8.16/tests/uuid.rs000064400000000000000000000003270072674642500142350ustar 00000000000000mod util; use util::*; #[test] fn uuid08() -> TestResult { test_default_generated_schema::("uuid") } #[test] fn uuid1() -> TestResult { test_default_generated_schema::("uuid") } schemars-0.8.16/tests/validate.rs000064400000000000000000000064230072674642500150630ustar 00000000000000mod util; use schemars::JsonSchema; use std::collections::HashMap; use util::*; // In real code, this would typically be a Regex, potentially created in a `lazy_static!`. static STARTS_WITH_HELLO: &str = r"^[Hh]ello\b"; const MIN: u32 = 1; const MAX: u32 = 1000; #[allow(dead_code)] #[derive(JsonSchema)] pub struct Struct { #[validate(range(min = 0.01, max = 100))] min_max: f32, #[validate(range(min = "MIN", max = "MAX"))] min_max2: f32, #[validate(regex = "STARTS_WITH_HELLO")] regex_str1: String, #[validate(regex(path = "STARTS_WITH_HELLO", code = "foo"))] regex_str2: String, #[validate(regex(pattern = r"^\d+$"))] regex_str3: String, #[validate(contains = "substring...")] contains_str1: String, #[validate(contains(pattern = "substring...", message = "bar"))] contains_str2: String, #[validate(email)] email_address: String, #[validate(phone)] tel: String, #[validate(url)] homepage: String, #[validate(length(min = 1, max = 100))] non_empty_str: String, #[validate(length(min = "MIN", max = "MAX"))] non_empty_str2: String, #[validate(length(equal = 2))] pair: Vec, #[validate(contains = "map_key")] map_contains: HashMap, #[validate(required)] required_option: Option, #[validate(required)] #[validate] #[serde(flatten)] required_flattened: Option, } #[allow(dead_code)] #[derive(JsonSchema)] pub struct Inner { x: i32, } #[test] fn validate() -> TestResult { test_default_generated_schema::("validate") } #[allow(dead_code)] #[derive(JsonSchema)] pub struct Struct2 { #[schemars(range(min = 0.01, max = 100))] min_max: f32, #[schemars(range(min = "MIN", max = "MAX"))] min_max2: f32, #[validate(regex = "overridden")] #[schemars(regex = "STARTS_WITH_HELLO")] regex_str1: String, #[schemars(regex(path = "STARTS_WITH_HELLO"))] regex_str2: String, #[schemars(regex(pattern = r"^\d+$"))] regex_str3: String, #[validate(regex = "overridden")] #[schemars(contains = "substring...")] contains_str1: String, #[schemars(contains(pattern = "substring..."))] contains_str2: String, #[schemars(email)] email_address: String, #[schemars(phone)] tel: String, #[schemars(url)] homepage: String, #[schemars(length(min = 1, max = 100))] non_empty_str: String, #[schemars(length(min = "MIN", max = "MAX"))] non_empty_str2: String, #[schemars(length(equal = 2))] pair: Vec, #[schemars(contains = "map_key")] map_contains: HashMap, #[schemars(required)] required_option: Option, #[schemars(required)] #[serde(flatten)] required_flattened: Option, } #[test] fn validate_schemars_attrs() -> TestResult { test_default_generated_schema::("validate_schemars_attrs") } #[derive(JsonSchema)] pub struct Tuple( #[validate(range(max = 10))] u8, #[validate(required)] Option, ); #[test] fn validate_tuple() -> TestResult { test_default_generated_schema::("validate_tuple") } #[derive(JsonSchema)] pub struct NewType(#[validate(range(max = 10))] u8); #[test] fn validate_newtype() -> TestResult { test_default_generated_schema::("validate_newtype") } schemars-0.8.16/tests/validate_inner.rs000064400000000000000000000017130072674642500162530ustar 00000000000000mod util; use schemars::JsonSchema; use util::*; // In real code, this would typically be a Regex, potentially created in a `lazy_static!`. static STARTS_WITH_HELLO: &str = r"^[Hh]ello\b"; #[allow(dead_code)] #[derive(JsonSchema)] pub struct Struct<'a> { #[schemars(inner(length(min = 5, max = 100)))] array_str_length: [&'a str; 2], #[schemars(inner(contains(pattern = "substring...")))] slice_str_contains: &'a[&'a str], #[schemars(inner(regex = "STARTS_WITH_HELLO"))] vec_str_regex: Vec, #[schemars(inner(length(min = 1, max = 100)))] vec_str_length: Vec<&'a str>, #[schemars(length(min = 1, max = 3), inner(length(min = 1, max = 100)))] vec_str_length2: Vec, #[schemars(inner(url))] vec_str_url: Vec, #[schemars(inner(range(min = -10, max = 10)))] vec_i32_range: Vec, } #[test] fn validate_inner() -> TestResult { test_default_generated_schema::("validate_inner") }