mirror of
https://gitlab.com/msrd0/gotham-restful.git
synced 2025-02-23 04:52:28 +00:00
Proper OpenAPI type for path parameters (Fixes #18)
This commit is contained in:
parent
9fd0bceaf4
commit
45eac21726
4 changed files with 28 additions and 16 deletions
|
@ -2,7 +2,6 @@ use crate::{
|
||||||
resource::*,
|
resource::*,
|
||||||
result::*,
|
result::*,
|
||||||
OpenapiSchema,
|
OpenapiSchema,
|
||||||
OpenapiType,
|
|
||||||
RequestBody
|
RequestBody
|
||||||
};
|
};
|
||||||
use super::SECURITY_NAME;
|
use super::SECURITY_NAME;
|
||||||
|
@ -18,7 +17,7 @@ use openapiv3::{
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct OperationParams<'a>
|
struct OperationParams<'a>
|
||||||
{
|
{
|
||||||
path_params : Vec<&'a str>,
|
path_params : Vec<(&'a str, ReferenceOr<Schema>)>,
|
||||||
query_params : Option<OpenapiSchema>
|
query_params : Option<OpenapiSchema>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,11 +29,11 @@ impl<'a> OperationParams<'a>
|
||||||
{
|
{
|
||||||
params.push(Item(Parameter::Path {
|
params.push(Item(Parameter::Path {
|
||||||
parameter_data: ParameterData {
|
parameter_data: ParameterData {
|
||||||
name: (*param).to_string(),
|
name: (*param).0.to_string(),
|
||||||
description: None,
|
description: None,
|
||||||
required: true,
|
required: true,
|
||||||
deprecated: None,
|
deprecated: None,
|
||||||
format: ParameterSchemaOrContent::Schema(Item(String::schema().into_schema())),
|
format: ParameterSchemaOrContent::Schema((*param).1.clone()),
|
||||||
example: None,
|
example: None,
|
||||||
examples: IndexMap::new()
|
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
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +191,7 @@ impl<'a> OperationDescription<'a>
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test
|
mod test
|
||||||
{
|
{
|
||||||
use crate::ResourceResult;
|
use crate::{OpenapiType, ResourceResult};
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -61,10 +61,11 @@ macro_rules! implOpenapiRouter {
|
||||||
fn read<Handler : ResourceRead>(&mut self)
|
fn read<Handler : ResourceRead>(&mut self)
|
||||||
{
|
{
|
||||||
let schema = (self.0).1.add_schema::<Handler::Res>();
|
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 path = format!("/{}/{{id}}", &self.1);
|
||||||
let mut item = (self.0).1.remove_path(&path);
|
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);
|
(self.0).1.add_path(path, item);
|
||||||
|
|
||||||
(&mut *(self.0).0, self.1).read::<Handler>()
|
(&mut *(self.0).0, self.1).read::<Handler>()
|
||||||
|
@ -120,11 +121,12 @@ macro_rules! implOpenapiRouter {
|
||||||
Handler::Body : 'static
|
Handler::Body : 'static
|
||||||
{
|
{
|
||||||
let schema = (self.0).1.add_schema::<Handler::Res>();
|
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 body_schema = (self.0).1.add_schema::<Handler::Body>();
|
||||||
|
|
||||||
let path = format!("/{}/{{id}}", &self.1);
|
let path = format!("/{}/{{id}}", &self.1);
|
||||||
let mut item = (self.0).1.remove_path(&path);
|
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);
|
(self.0).1.add_path(path, item);
|
||||||
|
|
||||||
(&mut *(self.0).0, self.1).update::<Handler>()
|
(&mut *(self.0).0, self.1).update::<Handler>()
|
||||||
|
@ -145,10 +147,11 @@ macro_rules! implOpenapiRouter {
|
||||||
fn delete<Handler : ResourceDelete>(&mut self)
|
fn delete<Handler : ResourceDelete>(&mut self)
|
||||||
{
|
{
|
||||||
let schema = (self.0).1.add_schema::<Handler::Res>();
|
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 path = format!("/{}/{{id}}", &self.1);
|
||||||
let mut item = (self.0).1.remove_path(&path);
|
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);
|
(self.0).1.add_path(path, item);
|
||||||
|
|
||||||
(&mut *(self.0).0, self.1).delete::<Handler>()
|
(&mut *(self.0).0, self.1).delete::<Handler>()
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
use crate::{DrawResourceRoutes, RequestBody, ResourceResult, ResourceType};
|
use crate::{DrawResourceRoutes, RequestBody, ResourceID, ResourceResult, ResourceType};
|
||||||
use gotham::{
|
use gotham::{
|
||||||
extractor::QueryStringExtractor,
|
extractor::QueryStringExtractor,
|
||||||
hyper::Body,
|
hyper::Body,
|
||||||
state::State
|
state::State
|
||||||
};
|
};
|
||||||
use serde::de::DeserializeOwned;
|
|
||||||
use std::{
|
use std::{
|
||||||
future::Future,
|
future::Future,
|
||||||
panic::RefUnwindSafe,
|
|
||||||
pin::Pin
|
pin::Pin
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,7 +46,7 @@ pub trait ResourceReadAll : ResourceMethod
|
||||||
/// Handle a GET request on the Resource with an id.
|
/// Handle a GET request on the Resource with an id.
|
||||||
pub trait ResourceRead : ResourceMethod
|
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>>;
|
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
|
pub trait ResourceUpdate : ResourceMethod
|
||||||
{
|
{
|
||||||
type Body : RequestBody;
|
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>>;
|
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.
|
/// Handle a DELETE request on the Resource with an id.
|
||||||
pub trait ResourceDelete : ResourceMethod
|
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>>;
|
fn delete(state : State, id : Self::ID) -> Pin<Box<dyn Future<Output = (State, Self::Res)> + Send>>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::result::ResourceError;
|
||||||
use gotham::hyper::body::Bytes;
|
use gotham::hyper::body::Bytes;
|
||||||
use mime::{Mime, APPLICATION_JSON};
|
use mime::{Mime, APPLICATION_JSON};
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
|
use std::panic::RefUnwindSafe;
|
||||||
|
|
||||||
#[cfg(not(feature = "openapi"))]
|
#[cfg(not(feature = "openapi"))]
|
||||||
pub trait ResourceType
|
pub trait ResourceType
|
||||||
|
@ -78,3 +79,14 @@ impl<T : ResourceType + DeserializeOwned> RequestBody for T
|
||||||
Some(vec![APPLICATION_JSON])
|
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
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue