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

Proper OpenAPI type for path parameters (Fixes #18)

This commit is contained in:
Dominic 2020-04-29 19:10:11 +02:00
parent 9fd0bceaf4
commit 45eac21726
Signed by: msrd0
GPG key ID: DCC8C247452E98F9
4 changed files with 28 additions and 16 deletions

View file

@ -2,7 +2,6 @@ use crate::{
resource::*,
result::*,
OpenapiSchema,
OpenapiType,
RequestBody
};
use super::SECURITY_NAME;
@ -18,7 +17,7 @@ use openapiv3::{
#[derive(Default)]
struct OperationParams<'a>
{
path_params : Vec<&'a str>,
path_params : Vec<(&'a str, ReferenceOr<Schema>)>,
query_params : Option<OpenapiSchema>
}
@ -30,11 +29,11 @@ impl<'a> OperationParams<'a>
{
params.push(Item(Parameter::Path {
parameter_data: ParameterData {
name: (*param).to_string(),
name: (*param).0.to_string(),
description: None,
required: true,
deprecated: None,
format: ParameterSchemaOrContent::Schema(Item(String::schema().into_schema())),
format: ParameterSchemaOrContent::Schema((*param).1.clone()),
example: None,
examples: IndexMap::new()
},
@ -110,9 +109,9 @@ impl<'a> OperationDescription<'a>
}
}
pub fn with_path_params(mut self, params : Vec<&'a str>) -> Self
pub fn add_path_param(mut self, name : &'a str, schema : ReferenceOr<Schema>) -> Self
{
self.params.path_params = params;
self.params.path_params.push((name, schema));
self
}
@ -192,7 +191,7 @@ impl<'a> OperationDescription<'a>
#[cfg(test)]
mod test
{
use crate::ResourceResult;
use crate::{OpenapiType, ResourceResult};
use super::*;
#[test]

View file

@ -61,10 +61,11 @@ macro_rules! implOpenapiRouter {
fn read<Handler : ResourceRead>(&mut self)
{
let schema = (self.0).1.add_schema::<Handler::Res>();
let id_schema = (self.0).1.add_schema::<Handler::ID>();
let path = format!("/{}/{{id}}", &self.1);
let mut item = (self.0).1.remove_path(&path);
item.get = Some(OperationDescription::new::<Handler>(schema).with_path_params(vec!["id"]).into_operation());
item.get = Some(OperationDescription::new::<Handler>(schema).add_path_param("id", id_schema).into_operation());
(self.0).1.add_path(path, item);
(&mut *(self.0).0, self.1).read::<Handler>()
@ -120,11 +121,12 @@ macro_rules! implOpenapiRouter {
Handler::Body : 'static
{
let schema = (self.0).1.add_schema::<Handler::Res>();
let id_schema = (self.0).1.add_schema::<Handler::ID>();
let body_schema = (self.0).1.add_schema::<Handler::Body>();
let path = format!("/{}/{{id}}", &self.1);
let mut item = (self.0).1.remove_path(&path);
item.put = Some(OperationDescription::new::<Handler>(schema).with_path_params(vec!["id"]).with_body::<Handler::Body>(body_schema).into_operation());
item.put = Some(OperationDescription::new::<Handler>(schema).add_path_param("id", id_schema).with_body::<Handler::Body>(body_schema).into_operation());
(self.0).1.add_path(path, item);
(&mut *(self.0).0, self.1).update::<Handler>()
@ -145,10 +147,11 @@ macro_rules! implOpenapiRouter {
fn delete<Handler : ResourceDelete>(&mut self)
{
let schema = (self.0).1.add_schema::<Handler::Res>();
let id_schema = (self.0).1.add_schema::<Handler::ID>();
let path = format!("/{}/{{id}}", &self.1);
let mut item = (self.0).1.remove_path(&path);
item.delete = Some(OperationDescription::new::<Handler>(schema).with_path_params(vec!["id"]).into_operation());
item.delete = Some(OperationDescription::new::<Handler>(schema).add_path_param("id", id_schema).into_operation());
(self.0).1.add_path(path, item);
(&mut *(self.0).0, self.1).delete::<Handler>()

View file

@ -1,13 +1,11 @@
use crate::{DrawResourceRoutes, RequestBody, ResourceResult, ResourceType};
use crate::{DrawResourceRoutes, RequestBody, ResourceID, ResourceResult, ResourceType};
use gotham::{
extractor::QueryStringExtractor,
hyper::Body,
state::State
};
use serde::de::DeserializeOwned;
use std::{
future::Future,
panic::RefUnwindSafe,
pin::Pin
};
@ -48,7 +46,7 @@ pub trait ResourceReadAll : ResourceMethod
/// Handle a GET request on the Resource with an id.
pub trait ResourceRead : ResourceMethod
{
type ID : DeserializeOwned + Clone + RefUnwindSafe + Send + Sync + 'static;
type ID : ResourceID + 'static;
fn read(state : State, id : Self::ID) -> Pin<Box<dyn Future<Output = (State, Self::Res)> + Send>>;
}
@ -81,7 +79,7 @@ pub trait ResourceUpdateAll : ResourceMethod
pub trait ResourceUpdate : ResourceMethod
{
type Body : RequestBody;
type ID : DeserializeOwned + Clone + RefUnwindSafe + Send + Sync + 'static;
type ID : ResourceID + 'static;
fn update(state : State, id : Self::ID, body : Self::Body) -> Pin<Box<dyn Future<Output = (State, Self::Res)> + Send>>;
}
@ -95,7 +93,7 @@ pub trait ResourceDeleteAll : ResourceMethod
/// Handle a DELETE request on the Resource with an id.
pub trait ResourceDelete : ResourceMethod
{
type ID : DeserializeOwned + Clone + RefUnwindSafe + Send + Sync + 'static;
type ID : ResourceID + 'static;
fn delete(state : State, id : Self::ID) -> Pin<Box<dyn Future<Output = (State, Self::Res)> + Send>>;
}

View file

@ -5,6 +5,7 @@ use crate::result::ResourceError;
use gotham::hyper::body::Bytes;
use mime::{Mime, APPLICATION_JSON};
use serde::{de::DeserializeOwned, Serialize};
use std::panic::RefUnwindSafe;
#[cfg(not(feature = "openapi"))]
pub trait ResourceType
@ -78,3 +79,14 @@ impl<T : ResourceType + DeserializeOwned> RequestBody for T
Some(vec![APPLICATION_JSON])
}
}
/// A type than can be used as a parameter to a resource method. Implemented for every type
/// that is deserialize and thread-safe. If the `openapi` feature is used, it must also be of
/// type `OpenapiType`.
pub trait ResourceID : ResourceType + DeserializeOwned + Clone + RefUnwindSafe + Send + Sync
{
}
impl<T : ResourceType + DeserializeOwned + Clone + RefUnwindSafe + Send + Sync> ResourceID for T
{
}