diff --git a/okapi/Cargo.toml b/okapi/Cargo.toml index 60e23be..3e7952b 100644 --- a/okapi/Cargo.toml +++ b/okapi/Cargo.toml @@ -21,6 +21,7 @@ log = { workspace = true } impl_json_schema = ["schemars/impl_json_schema"] # Preserve the order of items in schema and other part of the OpenAPI documentation. preserve_order = ["schemars/preserve_order"] +schemars-alpha = [] [package.metadata.docs.rs] all-features = true diff --git a/okapi/src/merge.rs b/okapi/src/merge.rs index fbe3257..2206368 100644 --- a/okapi/src/merge.rs +++ b/okapi/src/merge.rs @@ -151,6 +151,9 @@ pub fn merge_components( } else { if let Some(s1) = s1 { let s2 = s2.as_ref().unwrap(); + #[cfg(feature = "schemars-alpha")] + merge_map_json(&mut s1.schemas, s2.schemas.clone(), "schemas"); + #[cfg(not(feature = "schemars-alpha"))] merge_map(&mut s1.schemas, &s2.schemas, "schemas"); merge_map(&mut s1.responses, &s2.responses, "responses"); merge_map(&mut s1.parameters, &s2.parameters, "parameters"); @@ -264,6 +267,26 @@ pub fn merge_option(s1: &mut Option, s2: &Option) { } } +#[cfg(feature = "schemars-alpha")] +pub fn merge_map_json(s1: &mut serde_json::Value, s2: serde_json::Value, name: &str) { + if let serde_json::Value::Object(s1) = s1 { + if let serde_json::Value::Object(s2) = s2 { + for (k, v) in s2 { + if v.is_null() { + s1.remove(&k); + } + else { + merge_map_json(s1.entry(k).or_insert(serde_json::Value::Null), v, name); + } + } + + return; + } + } + + *s1 = s2; +} + /// Merge `Map`/`&Map`: /// Merge together. If key already exists, use s1 version. pub fn merge_map( diff --git a/okapi/src/openapi3.rs b/okapi/src/openapi3.rs index 3063d00..060ad90 100644 --- a/okapi/src/openapi3.rs +++ b/okapi/src/openapi3.rs @@ -214,6 +214,9 @@ pub struct Responses { #[cfg_attr(feature = "impl_json_schema", derive(JsonSchema))] #[serde(default, rename_all = "camelCase")] pub struct Components { + #[cfg(feature = "schemars-alpha")] + pub schemas: serde_json::Value, + #[cfg(not(feature = "schemars-alpha"))] #[serde(default, skip_serializing_if = "Map::is_empty")] pub schemas: Map, #[serde(default, skip_serializing_if = "Map::is_empty")] diff --git a/rocket-okapi/src/gen.rs b/rocket-okapi/src/gen.rs index 0a0882a..25f9de5 100644 --- a/rocket-okapi/src/gen.rs +++ b/rocket-okapi/src/gen.rs @@ -109,6 +109,7 @@ impl OpenApiGenerator { paths }, components: Some(Components { + #[cfg(not(feature = "schemars-alpha"))] schemas: schemas.into_iter().map(|(k, v)| (k, v.into())).collect(), security_schemes: schemes, ..Default::default()