Skip to content

Commit

Permalink
Add support for chrono::NaiveTime (#641)
Browse files Browse the repository at this point in the history
Add support for chrono `NaiveTime` in same way as chrono `Duration` has
been done. `SchemaType::String` will be used without any additional format
for `NaiveTime` types.

Update tests and docs for chrono.
---------

Co-authored-by: Juha Kukkonen <juha7kukkonen@gmail.com>
  • Loading branch information
beyarkay and juhaku authored Jun 11, 2023
1 parent f8c6d07 commit d9c4702
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ and the `ipa` is _api_ reversed. Aaand... `ipa` is also an awesome type of beer
defining the `parameter_in` attribute. See [docs](https://docs.rs/utoipa/latest/utoipa/attr.path.html#axum_extras-feature-support-for-axum)
or [examples](./examples) for more details.
- **debug** Add extra traits such as debug traits to openapi definitions and elsewhere.
- **chrono** Add support for [chrono](https://crates.io/crates/chrono) `DateTime`, `Date`, `NaiveDate`, `NaiveDateTime` and `Duration`
- **chrono** Add support for [chrono](https://crates.io/crates/chrono) `DateTime`, `Date`, `NaiveDate`, `NaiveDateTime`, `NaiveTime` and `Duration`
types. By default these types are parsed to `string` types with additional `format` information.
`format: date-time` for `DateTime` and `NaiveDateTime` and `format: date` for `Date` and `NaiveDate` according
[RFC3339](https://www.rfc-editor.org/rfc/rfc3339#section-5.6) as `ISO-8601`. To
Expand Down
4 changes: 2 additions & 2 deletions utoipa-gen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ rust_decimal = "1"
chrono = { version = "0.4", features = ["serde"] }
assert-json-diff = "2"
time = { version = "0.3", features = ["serde-human-readable"] }
serde_with = "2.3"
serde_with = "3.0"

[features]
# See README.md for list and explanations of features
Expand All @@ -45,7 +45,7 @@ yaml = []
decimal = []
rocket_extras = ["regex", "lazy_static", "syn/extra-traits"]
non_strict_integers = []
uuid = ["dep:uuid"]
uuid = ["dep:uuid", "utoipa/uuid"]
axum_extras = ["syn/extra-traits"]
time = []
smallvec = []
Expand Down
27 changes: 21 additions & 6 deletions utoipa-gen/src/schema_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ fn is_primitive(name: &str) -> bool {
fn is_primitive_chrono(name: &str) -> bool {
matches!(
name,
"DateTime" | "Date" | "NaiveDate" | "Duration" | "NaiveDateTime"
"DateTime" | "Date" | "NaiveDate" | "NaiveTime" | "Duration" | "NaiveDateTime"
)
}

Expand All @@ -174,24 +174,30 @@ impl ToTokens for SchemaType<'_> {
"String" | "str" | "char" => {
tokens.extend(quote! {utoipa::openapi::SchemaType::String})
}

"bool" => tokens.extend(quote! { utoipa::openapi::SchemaType::Boolean }),

"i8" | "i16" | "i32" | "i64" | "i128" | "isize" | "u8" | "u16" | "u32" | "u64"
| "u128" | "usize" => tokens.extend(quote! { utoipa::openapi::SchemaType::Integer }),
"f32" | "f64" => tokens.extend(quote! { utoipa::openapi::SchemaType::Number }),

#[cfg(feature = "chrono")]
"DateTime" => tokens.extend(quote! { utoipa::openapi::SchemaType::String }),
#[cfg(feature = "chrono")]
"NaiveDateTime" => tokens.extend(quote! { utoipa::openapi::SchemaType::String }),
#[cfg(feature = "chrono")]
"NaiveDate" => tokens.extend(quote!(utoipa::openapi::SchemaType::String)),
"DateTime" | "NaiveDateTime" | "NaiveDate" | "NaiveTime" => {
tokens.extend(quote! { utoipa::openapi::SchemaType::String })
}

#[cfg(any(feature = "chrono", feature = "time"))]
"Date" | "Duration" => tokens.extend(quote! { utoipa::openapi::SchemaType::String }),

#[cfg(feature = "decimal")]
"Decimal" => tokens.extend(quote! { utoipa::openapi::SchemaType::String }),

#[cfg(feature = "rocket_extras")]
"PathBuf" => tokens.extend(quote! { utoipa::openapi::SchemaType::String }),

#[cfg(feature = "uuid")]
"Uuid" => tokens.extend(quote! { utoipa::openapi::SchemaType::String }),

#[cfg(feature = "time")]
"PrimitiveDateTime" | "OffsetDateTime" => {
tokens.extend(quote! { utoipa::openapi::SchemaType::String })
Expand Down Expand Up @@ -313,26 +319,35 @@ impl ToTokens for Type<'_> {
"u32" => tokens.extend(quote! { utoipa::openapi::SchemaFormat::KnownFormat(utoipa::openapi::KnownFormat::UInt32) }),
#[cfg(feature="non_strict_integers")]
"u64" => tokens.extend(quote! { utoipa::openapi::SchemaFormat::KnownFormat(utoipa::openapi::KnownFormat::UInt64) }),

#[cfg(not(feature="non_strict_integers"))]
"i8" | "i16" | "u8" | "u16" | "u32" => {
tokens.extend(quote! { utoipa::openapi::SchemaFormat::KnownFormat(utoipa::openapi::KnownFormat::Int32) })
}

#[cfg(not(feature="non_strict_integers"))]
"u64" => tokens.extend(quote! { utoipa::openapi::SchemaFormat::KnownFormat(utoipa::openapi::KnownFormat::Int64) }),

"i32" => tokens.extend(quote! { utoipa::openapi::SchemaFormat::KnownFormat(utoipa::openapi::KnownFormat::Int32) }),
"i64" => tokens.extend(quote! { utoipa::openapi::SchemaFormat::KnownFormat(utoipa::openapi::KnownFormat::Int64) }),
"f32" => tokens.extend(quote! { utoipa::openapi::SchemaFormat::KnownFormat(utoipa::openapi::KnownFormat::Float) }),
"f64" => tokens.extend(quote! { utoipa::openapi::SchemaFormat::KnownFormat(utoipa::openapi::KnownFormat::Double) }),

#[cfg(feature = "chrono")]
"NaiveDate" => tokens.extend(quote! { utoipa::openapi::SchemaFormat::KnownFormat(utoipa::openapi::KnownFormat::Date) }),

#[cfg(feature = "chrono")]
"DateTime" => tokens.extend(quote! { utoipa::openapi::SchemaFormat::KnownFormat(utoipa::openapi::KnownFormat::DateTime) }),

#[cfg(feature = "chrono")]
"NaiveDateTime" => tokens.extend(quote! { utoipa::openapi::SchemaFormat::KnownFormat(utoipa::openapi::KnownFormat::DateTime) }),

#[cfg(any(feature = "chrono", feature = "time"))]
"Date" => tokens.extend(quote! { utoipa::openapi::SchemaFormat::KnownFormat(utoipa::openapi::KnownFormat::Date) }),

#[cfg(feature = "uuid")]
"Uuid" => tokens.extend(quote! { utoipa::openapi::SchemaFormat::KnownFormat(utoipa::openapi::KnownFormat::Uuid) }),

#[cfg(feature = "time")]
"PrimitiveDateTime" | "OffsetDateTime" => {
tokens.extend(quote! { utoipa::openapi::SchemaFormat::KnownFormat(utoipa::openapi::KnownFormat::DateTime) })
Expand Down
5 changes: 4 additions & 1 deletion utoipa-gen/tests/schema_derive_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2694,7 +2694,7 @@ fn derive_struct_xml_with_optional_vec() {
#[test]
fn derive_component_with_chrono_feature() {
#![allow(deprecated)] // allow deprecated Date in tests as long as it is available from chrono
use chrono::{Date, DateTime, Duration, NaiveDate, NaiveDateTime, Utc};
use chrono::{Date, DateTime, Duration, NaiveDate, NaiveDateTime, NaiveTime, Utc};

let post = api_doc! {
struct Post {
Expand All @@ -2704,6 +2704,7 @@ fn derive_component_with_chrono_feature() {
naive_datetime: NaiveDateTime,
date: Date<Utc>,
naive_date: NaiveDate,
naive_time: NaiveTime,
duration: Duration,
}
};
Expand All @@ -2717,6 +2718,8 @@ fn derive_component_with_chrono_feature() {
"properties.date.format" = r#""date""#, "Post date format"
"properties.naive_date.type" = r#""string""#, "Post date type"
"properties.naive_date.format" = r#""date""#, "Post date format"
"properties.naive_time.type" = r#""string""#, "Post time type"
"properties.naive_time.format" = r#"null"#, "Post time format"
"properties.duration.type" = r#""string""#, "Post duration type"
"properties.duration.format" = r#"null"#, "Post duration format"
"properties.id.type" = r#""integer""#, "Post id type"
Expand Down
2 changes: 1 addition & 1 deletion utoipa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
//! without defining the `parameter_in` attribute. See [axum extras support][axum_path]
//! or [examples](https://github.com/juhaku/utoipa/tree/master/examples) for more details.
//! * **debug** Add extra traits such as debug traits to openapi definitions and elsewhere.
//! * **chrono** Add support for [chrono](https://crates.io/crates/chrono) `DateTime`, `Date`, `NaiveDate` and `Duration`
//! * **chrono** Add support for [chrono](https://crates.io/crates/chrono) `DateTime`, `Date`, `NaiveDate`, `NaiveTime` and `Duration`
//! types. By default these types are parsed to `string` types with additional `format` information.
//! `format: date-time` for `DateTime` and `format: date` for `Date` and `NaiveDate` according
//! [RFC3339](https://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14) as `ISO-8601`. To
Expand Down

0 comments on commit d9c4702

Please sign in to comment.