From 675f2af925612f1b3be9e3ffbea4b00bd8d666b8 Mon Sep 17 00:00:00 2001 From: James Tomlinson Date: Fri, 1 Dec 2023 12:09:59 +0000 Subject: [PATCH] feat: Add impls for the time crate. --- schemars/Cargo.toml | 5 ++++ schemars/src/json_schema_impls/mod.rs | 2 ++ schemars/src/json_schema_impls/time.rs | 35 +++++++++++++++++++++++++ schemars/tests/expected/time-types.json | 29 ++++++++++++++++++++ schemars/tests/time.rs | 18 +++++++++++++ schemars/tests/validate_inner.rs | 2 +- 6 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 schemars/src/json_schema_impls/time.rs create mode 100644 schemars/tests/expected/time-types.json create mode 100644 schemars/tests/time.rs diff --git a/schemars/Cargo.toml b/schemars/Cargo.toml index fb6b06e5..009ce989 100644 --- a/schemars/Cargo.toml +++ b/schemars/Cargo.toml @@ -36,6 +36,7 @@ bigdecimal04 = { version = "0.4", default-features = false, optional = true, pac enumset = { version = "1.0", optional = true } smol_str = { version = "0.1.17", optional = true } semver = { version = "1.0.9", features = ["serde"], optional = true } +time = { version = "0.3.30", default-features = false, optional = true } [dev-dependencies] pretty_assertions = "1.2.1" @@ -127,5 +128,9 @@ required-features = ["semver"] name = "decimal" required-features = ["rust_decimal", "bigdecimal03", "bigdecimal04"] +[[test]] +name = "time" +required-features = ["time"] + [package.metadata.docs.rs] all-features = true diff --git a/schemars/src/json_schema_impls/mod.rs b/schemars/src/json_schema_impls/mod.rs index c944203a..1b30d48f 100644 --- a/schemars/src/json_schema_impls/mod.rs +++ b/schemars/src/json_schema_impls/mod.rs @@ -79,6 +79,8 @@ mod smallvec; #[cfg(feature = "smol_str")] mod smol_str; mod std_time; +#[cfg(feature = "time")] +mod time; mod tuple; #[cfg(feature = "url")] mod url; diff --git a/schemars/src/json_schema_impls/time.rs b/schemars/src/json_schema_impls/time.rs new file mode 100644 index 00000000..5737349b --- /dev/null +++ b/schemars/src/json_schema_impls/time.rs @@ -0,0 +1,35 @@ +use crate::gen::SchemaGenerator; +use crate::schema::*; +use crate::JsonSchema; +use std::borrow::Cow; +use time::{Date, OffsetDateTime, PrimitiveDateTime, Time}; + +macro_rules! formatted_string_impl { + ($ty:ident, $format:literal) => { + impl JsonSchema for $ty { + no_ref_schema!(); + + fn schema_name() -> String { + stringify!($ty).to_owned() + } + + fn schema_id() -> Cow<'static, str> { + Cow::Borrowed(stringify!(time::$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!(Date, "date"); +formatted_string_impl!(PrimitiveDateTime, "partial-date-time"); +formatted_string_impl!(Time, "time"); +formatted_string_impl!(OffsetDateTime, "date-time"); diff --git a/schemars/tests/expected/time-types.json b/schemars/tests/expected/time-types.json new file mode 100644 index 00000000..d9ada5b5 --- /dev/null +++ b/schemars/tests/expected/time-types.json @@ -0,0 +1,29 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "TimeTypes", + "type": "object", + "required": [ + "date", + "offset_date_time", + "primitive_date_time", + "time" + ], + "properties": { + "date": { + "type": "string", + "format": "date" + }, + "time": { + "type": "string", + "format": "time" + }, + "primitive_date_time": { + "type": "string", + "format": "partial-date-time" + }, + "offset_date_time": { + "type": "string", + "format": "date-time" + } + } +} \ No newline at end of file diff --git a/schemars/tests/time.rs b/schemars/tests/time.rs new file mode 100644 index 00000000..c727d3c9 --- /dev/null +++ b/schemars/tests/time.rs @@ -0,0 +1,18 @@ +mod util; +use schemars::JsonSchema; +use time::{Date, OffsetDateTime, PrimitiveDateTime, Time}; +use util::*; + +#[allow(dead_code)] +#[derive(JsonSchema)] +struct TimeTypes { + date: Date, + time: Time, + primitive_date_time: PrimitiveDateTime, + offset_date_time: OffsetDateTime, +} + +#[test] +fn time_types() -> TestResult { + test_default_generated_schema::("time-types") +} diff --git a/schemars/tests/validate_inner.rs b/schemars/tests/validate_inner.rs index 535410f1..64166719 100644 --- a/schemars/tests/validate_inner.rs +++ b/schemars/tests/validate_inner.rs @@ -12,7 +12,7 @@ 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], + slice_str_contains: &'a [&'a str], #[schemars(inner(regex = "STARTS_WITH_HELLO"))] vec_str_regex: Vec, #[schemars(inner(length(min = 1, max = 100)))]