From 01545b28d243236d6d67225938ca65c01abf9980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Kristensen?= Date: Thu, 9 Mar 2023 11:17:14 +0100 Subject: [PATCH 1/2] implement JsonSchema trait for time::OffsetDateTime --- schemars/Cargo.toml | 1 + schemars/src/json_schema_impls/mod.rs | 2 + schemars/src/json_schema_impls/std_time.rs | 46 +++++++++++++++++++++ schemars/src/json_schema_impls/time.rs | 47 +++++----------------- schemars/src/lib.rs | 1 + 5 files changed, 60 insertions(+), 37 deletions(-) create mode 100644 schemars/src/json_schema_impls/std_time.rs diff --git a/schemars/Cargo.toml b/schemars/Cargo.toml index ad972dd9..f8ba6cc4 100644 --- a/schemars/Cargo.toml +++ b/schemars/Cargo.toml @@ -18,6 +18,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.25" dyn-clone = "1.0" +time = { version = "0.3", default-features = false, optional = true } chrono = { version = "0.4", default-features = false, optional = true } indexmap = { version = "1.2", features = ["serde-1"], optional = true } either = { version = "1.3", default-features = false, optional = true } diff --git a/schemars/src/json_schema_impls/mod.rs b/schemars/src/json_schema_impls/mod.rs index 490a544e..a72ead93 100644 --- a/schemars/src/json_schema_impls/mod.rs +++ b/schemars/src/json_schema_impls/mod.rs @@ -66,6 +66,8 @@ mod serdejson; mod smallvec; #[cfg(feature = "smol_str")] mod smol_str; +mod std_time; +#[cfg(feature = "time")] mod time; mod tuple; #[cfg(feature = "url")] diff --git a/schemars/src/json_schema_impls/std_time.rs b/schemars/src/json_schema_impls/std_time.rs new file mode 100644 index 00000000..f4362eef --- /dev/null +++ b/schemars/src/json_schema_impls/std_time.rs @@ -0,0 +1,46 @@ +use crate::gen::SchemaGenerator; +use crate::schema::*; +use crate::JsonSchema; +use std::time::{Duration, SystemTime}; + +impl JsonSchema for Duration { + fn schema_name() -> String { + "Duration".to_owned() + } + + 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 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() + } +} diff --git a/schemars/src/json_schema_impls/time.rs b/schemars/src/json_schema_impls/time.rs index f4362eef..a6d9ca5e 100644 --- a/schemars/src/json_schema_impls/time.rs +++ b/schemars/src/json_schema_impls/time.rs @@ -1,46 +1,19 @@ use crate::gen::SchemaGenerator; -use crate::schema::*; +use crate::schema::{InstanceType, Schema, SchemaObject}; use crate::JsonSchema; -use std::time::{Duration, SystemTime}; +use time::OffsetDateTime; -impl JsonSchema for Duration { +impl JsonSchema for OffsetDateTime { fn schema_name() -> String { - "Duration".to_owned() + "DateTime".into() } - fn json_schema(gen: &mut SchemaGenerator) -> Schema { - let mut schema = SchemaObject { - instance_type: Some(InstanceType::Object.into()), + fn json_schema(_: &mut SchemaGenerator) -> Schema { + SchemaObject { + instance_type: Some(InstanceType::String.into()), + format: Some("date-time".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 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() + } + .into() } } diff --git a/schemars/src/lib.rs b/schemars/src/lib.rs index 796ec272..59ffaa2a 100644 --- a/schemars/src/lib.rs +++ b/schemars/src/lib.rs @@ -261,6 +261,7 @@ println!("{}", serde_json::to_string_pretty(&schema).unwrap()); 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) +- `time` - [time](https://crates.io/crates/time) (^0.3) - `indexmap1` - [indexmap](https://crates.io/crates/indexmap) (^1.2) - `either` - [either](https://crates.io/crates/either) (^1.3) - `uuid08` - [uuid](https://crates.io/crates/uuid) (^0.8) From ff5ff0257b61b7c70e1dd9df6163820294e3aef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Kristensen?= Date: Fri, 24 Mar 2023 12:36:03 +0100 Subject: [PATCH 2/2] time schema should not be referencable --- schemars/src/json_schema_impls/time.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/schemars/src/json_schema_impls/time.rs b/schemars/src/json_schema_impls/time.rs index a6d9ca5e..60e39545 100644 --- a/schemars/src/json_schema_impls/time.rs +++ b/schemars/src/json_schema_impls/time.rs @@ -4,6 +4,10 @@ use crate::JsonSchema; use time::OffsetDateTime; impl JsonSchema for OffsetDateTime { + fn is_referenceable() -> bool { + false + } + fn schema_name() -> String { "DateTime".into() }