Add example for remote deriving JsonSchema
This commit is contained in:
parent
b11536e527
commit
8d40625f10
5 changed files with 165 additions and 0 deletions
38
docs/_includes/examples/remote_derive.rs
Normal file
38
docs/_includes/examples/remote_derive.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
// 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)]
|
||||
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,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let schema = schema_for!(Process);
|
||||
println!("{}", serde_json::to_string_pretty(&schema).unwrap());
|
||||
}
|
36
docs/_includes/examples/remote_derive.schema.json
Normal file
36
docs/_includes/examples/remote_derive.schema.json
Normal file
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"$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/DurationDef"
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"DurationDef": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"nanos",
|
||||
"secs"
|
||||
],
|
||||
"properties": {
|
||||
"nanos": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"secs": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
17
docs/examples/5-remote_derive.md
Normal file
17
docs/examples/5-remote_derive.md
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
layout: default
|
||||
title: Derive for Remote Crate
|
||||
parent: Examples
|
||||
nav_order: 5
|
||||
summary: Deriving JsonSchema implementations for a type in somebody else's crate.
|
||||
---
|
||||
|
||||
# Deriving JsonSchema for a Type in a Different Crate
|
||||
|
||||
Rust's [orphan rule](https://doc.rust-lang.org/book/traits.html#rules-for-implementing-traits) requires that either the trait or the type for which you are implementing the trait must be defined in the same crate as the impl, so it is not possible to implement `JsonSchema` for a type in a different crate directly.
|
||||
|
||||
To work around this, Schemars provides a way of deriving `JsonSchema` implementations for types in other people's crates. The only catch is that you have to provide a definition of the type for Schemars's derive to process.
|
||||
|
||||
This is the same way that Serde allows remote deriving, which is why this page reads so similarly to [Serde's documentation](https://serde.rs/remote-derive.html)!
|
||||
|
||||
{% include example.md name="remote_derive" %}
|
38
schemars/examples/remote_derive.rs
Normal file
38
schemars/examples/remote_derive.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
// 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)]
|
||||
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,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let schema = schema_for!(Process);
|
||||
println!("{}", serde_json::to_string_pretty(&schema).unwrap());
|
||||
}
|
36
schemars/examples/remote_derive.schema.json
Normal file
36
schemars/examples/remote_derive.schema.json
Normal file
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"$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/DurationDef"
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"DurationDef": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"nanos",
|
||||
"secs"
|
||||
],
|
||||
"properties": {
|
||||
"nanos": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"secs": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue