1
0
Fork 0
mirror of https://gitlab.com/msrd0/gotham-restful.git synced 2025-02-22 20:52:27 +00:00

OpenAPI: Key Schema for HashMap's

This commit is contained in:
msrd0 2021-02-24 18:53:44 +00:00
parent e7ef6bdf5a
commit 7ed98c82e8
2 changed files with 23 additions and 3 deletions

View file

@ -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 - 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 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` - 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 ### Removed
- All pre-defined methods (`read`, `create`, ...) from our router extensions ([!18]) - All pre-defined methods (`read`, `create`, ...) from our router extensions ([!18])

View file

@ -344,10 +344,24 @@ impl<T: OpenapiType, S: BuildHasher> OpenapiType for HashSet<T, S> {
} }
} }
impl<K, T: OpenapiType, S: BuildHasher> OpenapiType for HashMap<K, T, S> { impl<K: OpenapiType, T: OpenapiType, S: BuildHasher> OpenapiType for HashMap<K, T, S> {
fn schema() -> OpenapiSchema { 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 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() { let items = Box::new(match schema.name.clone() {
Some(name) => { Some(name) => {
@ -360,10 +374,15 @@ impl<K, T: OpenapiType, S: BuildHasher> OpenapiType for HashMap<K, T, S> {
None => Item(schema.into_schema()) None => Item(schema.into_schema())
}); });
let mut properties = IndexMap::new();
properties.insert("default".to_owned(), keys);
OpenapiSchema { OpenapiSchema {
nullable: false, nullable: false,
name: None, name: None,
schema: SchemaKind::Type(Type::Object(ObjectType { schema: SchemaKind::Type(Type::Object(ObjectType {
properties,
required: vec!["default".to_owned()],
additional_properties: Some(AdditionalProperties::Schema(items)), additional_properties: Some(AdditionalProperties::Schema(items)),
..Default::default() ..Default::default()
})), })),
@ -453,6 +472,6 @@ mod test {
assert_schema!(Vec<String> => r#"{"type":"array","items":{"type":"string"}}"#); assert_schema!(Vec<String> => r#"{"type":"array","items":{"type":"string"}}"#);
assert_schema!(BTreeSet<String> => r#"{"type":"array","items":{"type":"string"}}"#); assert_schema!(BTreeSet<String> => r#"{"type":"array","items":{"type":"string"}}"#);
assert_schema!(HashSet<String> => r#"{"type":"array","items":{"type":"string"}}"#); assert_schema!(HashSet<String> => r#"{"type":"array","items":{"type":"string"}}"#);
assert_schema!(HashMap<String, String> => r#"{"type":"object","additionalProperties":{"type":"string"}}"#); assert_schema!(HashMap<i64, String> => r#"{"type":"object","properties":{"default":{"type":"integer","format":"int64"}},"required":["default"],"additionalProperties":{"type":"string"}}"#);
assert_schema!(Value => r#"{"nullable":true}"#); assert_schema!(Value => r#"{"nullable":true}"#);
} }