diff --git a/Cargo.toml b/Cargo.toml index 94a609163..54d31dd8e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -134,6 +134,7 @@ ulid = { version = "1", default-features = false } url = "2" uuid = "1" x509-parser = "0.16" +compact_str = { version = "0.7", features = ["serde"] } # Compress brotli = { version = "7", default-features = false } diff --git a/crates/oapi-macros/Cargo.toml b/crates/oapi-macros/Cargo.toml index 7ca1957d5..91d3fa249 100644 --- a/crates/oapi-macros/Cargo.toml +++ b/crates/oapi-macros/Cargo.toml @@ -29,6 +29,7 @@ smallvec = [] repr = [] indexmap = [] non-strict-integers = [] +compact_str = [] [dependencies] proc-macro2 = { workspace = true } @@ -49,6 +50,7 @@ assert-json-diff = { workspace = true } time = { workspace = true, features = ["serde-human-readable"] } serde_with = { workspace = true } paste = { workspace = true } +compact_str = { workspace = true, features = ["serde"] } [lints] workspace = true \ No newline at end of file diff --git a/crates/oapi-macros/src/schema_type.rs b/crates/oapi-macros/src/schema_type.rs index 0b517ff34..c9c811370 100644 --- a/crates/oapi-macros/src/schema_type.rs +++ b/crates/oapi-macros/src/schema_type.rs @@ -78,6 +78,7 @@ impl SchemaType<'_> { feature = "ulid", feature = "uuid", feature = "time", + feature = "compact_str" )))] { is_primitive(name) @@ -91,6 +92,7 @@ impl SchemaType<'_> { feature = "ulid", feature = "uuid", feature = "time", + feature = "compact_str" ))] { let mut primitive = is_primitive(name); @@ -125,6 +127,10 @@ impl SchemaType<'_> { "Date" | "PrimitiveDateTime" | "OffsetDateTime" | "Duration" ); } + #[cfg(feature = "compact_str")] + if !primitive { + primitive = matches!(name, "CompactString"); + } primitive } @@ -246,6 +252,10 @@ impl TryToTokens for SchemaType<'_> { "Date" | "Duration" => { schema_type_tokens(tokens, oapi, SchemaTypeInner::String, self.nullable) } + #[cfg(feature = "compact_str")] + "CompactString" => { + schema_type_tokens(tokens, oapi, SchemaTypeInner::String, self.nullable) + } #[cfg(all(feature = "decimal", feature = "decimal-float"))] "Decimal" => schema_type_tokens(tokens, oapi, SchemaTypeInner::String, self.nullable), #[cfg(all(feature = "decimal", not(feature = "decimal-float")))] @@ -333,7 +343,8 @@ impl Type<'_> { feature = "url", feature = "ulid", feature = "uuid", - feature = "time" + feature = "time", + feature = "compact_str" )))] { is_known_format(name) @@ -346,7 +357,8 @@ impl Type<'_> { feature = "url", feature = "ulid", feature = "uuid", - feature = "time" + feature = "time", + feature = "compact_str" ))] { let mut known_format = is_known_format(name); @@ -381,6 +393,11 @@ impl Type<'_> { known_format = matches!(name, "Date" | "PrimitiveDateTime" | "OffsetDateTime"); } + #[cfg(feature = "compact_str")] + if !known_format { + known_format = matches!(name, "CompactString"); + } + known_format } } @@ -460,6 +477,10 @@ impl TryToTokens for Type<'_> { "NaiveDateTime" => { tokens.extend(quote! { #oapi::oapi::SchemaFormat::KnownFormat(#oapi::oapi::KnownFormat::DateTime) }) } + #[cfg(feature = "compact_str")] + "CompactString" => { + tokens.extend(quote! { #oapi::oapi::SchemaFormat::KnownFormat(#oapi::oapi::KnownFormat::String) }) + } #[cfg(feature = "time")] "Date" => tokens.extend(quote! { #oapi::oapi::SchemaFormat::KnownFormat(#oapi::oapi::KnownFormat::Date) }), #[cfg(feature = "url")] diff --git a/crates/oapi/Cargo.toml b/crates/oapi/Cargo.toml index b67172908..2b16f70e4 100644 --- a/crates/oapi/Cargo.toml +++ b/crates/oapi/Cargo.toml @@ -15,7 +15,7 @@ authors = ["Juha Kukkonen ", "Chrislearn Young RefOr { crate::RefOr::Type(Schema::OneOf( @@ -212,6 +213,8 @@ impl ToSchema for chrono::DateTime { schema!(#[inline] DateTime).into() } } +#[cfg(feature = "compact_str")] +impl_to_schema_primitive!(compact_str::CompactString); #[cfg(any(feature = "decimal", feature = "decimal-float"))] impl_to_schema!(rust_decimal::Decimal); #[cfg(feature = "url")] diff --git a/crates/oapi/src/openapi/schema/mod.rs b/crates/oapi/src/openapi/schema/mod.rs index 53bc38a58..29050eb8f 100644 --- a/crates/oapi/src/openapi/schema/mod.rs +++ b/crates/oapi/src/openapi/schema/mod.rs @@ -512,6 +512,8 @@ pub enum KnownFormat { Duration, /// Hint to UI to obscure input. Password, + /// Use for compact string + String, /// Used with [`String`] values to indicate value is in decimal format. /// /// **decimal** feature need to be enabled. diff --git a/examples/oapi-todos/Cargo.toml b/examples/oapi-todos/Cargo.toml index a7d9d2cf7..786920adf 100644 --- a/examples/oapi-todos/Cargo.toml +++ b/examples/oapi-todos/Cargo.toml @@ -10,5 +10,6 @@ salvo = { workspace = true, features = ["oapi"] } serde = { workspace = true, features = ["derive"] } serde_json = "1" tokio = { workspace = true, features = ["macros"] } +compact_str = { version = "0.7", features = ["serde"] } tracing.workspace = true tracing-subscriber.workspace = true \ No newline at end of file