From 7ed98c82e820899cd0dd57cd2f0df62a826a252a Mon Sep 17 00:00:00 2001 From: msrd0 <1182023-msrd0@users.noreply.gitlab.com> Date: Wed, 24 Feb 2021 18:53:44 +0000 Subject: [PATCH] OpenAPI: Key Schema for HashMap's --- CHANGELOG.md | 1 + src/openapi/types.rs | 25 ++++++++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 372120c..3349897 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - If not enabling the `openapi` feature, `without-openapi` has to be enabled - The endpoint macro attributes (`read`, `create`, ...) no longer take the resource ident and reject all unknown attributes ([!18]) - The `ResourceResult` trait has been split into `ResourceResult` and `ResourceResultSchema` + - `HashMap`'s keys are included in the generated OpenAPI spec (they defaulted to `type: string` previously) ### Removed - All pre-defined methods (`read`, `create`, ...) from our router extensions ([!18]) diff --git a/src/openapi/types.rs b/src/openapi/types.rs index e15a6b5..18f5be6 100644 --- a/src/openapi/types.rs +++ b/src/openapi/types.rs @@ -344,10 +344,24 @@ impl OpenapiType for HashSet { } } -impl OpenapiType for HashMap { +impl OpenapiType for HashMap { fn schema() -> OpenapiSchema { + let key_schema = K::schema(); + let mut dependencies = key_schema.dependencies.clone(); + + let keys = match key_schema.name.clone() { + Some(name) => { + let reference = Reference { + reference: format!("#/components/schemas/{}", name) + }; + dependencies.insert(name, key_schema); + reference + }, + None => Item(Box::new(key_schema.into_schema())) + }; + let schema = T::schema(); - let mut dependencies = schema.dependencies.clone(); + dependencies.extend(schema.dependencies.iter().map(|(k, v)| (k.clone(), v.clone()))); let items = Box::new(match schema.name.clone() { Some(name) => { @@ -360,10 +374,15 @@ impl OpenapiType for HashMap { None => Item(schema.into_schema()) }); + let mut properties = IndexMap::new(); + properties.insert("default".to_owned(), keys); + OpenapiSchema { nullable: false, name: None, schema: SchemaKind::Type(Type::Object(ObjectType { + properties, + required: vec!["default".to_owned()], additional_properties: Some(AdditionalProperties::Schema(items)), ..Default::default() })), @@ -453,6 +472,6 @@ mod test { assert_schema!(Vec => r#"{"type":"array","items":{"type":"string"}}"#); assert_schema!(BTreeSet => r#"{"type":"array","items":{"type":"string"}}"#); assert_schema!(HashSet => r#"{"type":"array","items":{"type":"string"}}"#); - assert_schema!(HashMap => r#"{"type":"object","additionalProperties":{"type":"string"}}"#); + assert_schema!(HashMap => r#"{"type":"object","properties":{"default":{"type":"integer","format":"int64"}},"required":["default"],"additionalProperties":{"type":"string"}}"#); assert_schema!(Value => r#"{"nullable":true}"#); }