Skip to content

Commit

Permalink
Feature responses (#10)
Browse files Browse the repository at this point in the history
* Add derive responses for openapi schema

* Add tests for path responses
  • Loading branch information
juhaku authored Jan 16, 2022
1 parent 3be6dbe commit b7b37b4
Show file tree
Hide file tree
Showing 18 changed files with 796 additions and 238 deletions.
17 changes: 17 additions & 0 deletions src/openapi/content.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use serde::{Deserialize, Serialize};

use super::Component;

#[derive(Serialize, Deserialize, Default)]
#[non_exhaustive]
pub struct Content {
pub schema: Component,
}

impl Content {
pub fn new<I: Into<Component>>(schema: I) -> Self {
Self {
schema: schema.into(),
}
}
}
36 changes: 36 additions & 0 deletions src/openapi/header.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use serde::{Deserialize, Serialize};

use super::{Component, ComponentType, Property};

#[non_exhaustive]
#[derive(Serialize, Deserialize)]
pub struct Header {
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,

pub schema: Component,
}

impl Header {
pub fn new<C: Into<Component>>(component: C) -> Self {
Self {
schema: component.into(),
..Default::default()
}
}

pub fn with_description<S: AsRef<str>>(mut self, description: S) -> Self {
self.description = Some(description.as_ref().to_string());

self
}
}

impl Default for Header {
fn default() -> Self {
Self {
description: Default::default(),
schema: Property::new(ComponentType::String).into(),
}
}
}
5 changes: 5 additions & 0 deletions src/openapi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,23 @@ use crate::error::Error;

pub use self::{
contact::Contact,
content::Content,
external_docs::ExternalDocs,
header::Header,
info::Info,
licence::Licence,
path::{PathItem, PathItemType, Paths},
response::{Response, Responses},
schema::{Array, Component, ComponentFormat, ComponentType, Object, Property, Ref, Schema},
security::Security,
server::Server,
tag::Tag,
};

pub mod contact;
pub mod content;
pub mod external_docs;
pub mod header;
pub mod info;
pub mod licence;
pub mod path;
Expand Down
28 changes: 10 additions & 18 deletions src/openapi/request_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::HashMap;

use serde::{Deserialize, Serialize};

use super::{Component, Required};
use super::{Component, Content, Required};

#[non_exhaustive]
#[derive(Serialize, Deserialize, Default)]
Expand Down Expand Up @@ -34,24 +34,16 @@ impl RequestBody {
self
}

pub fn with_content<S: AsRef<str>>(mut self, content_type: S, content: Content) -> Self {
self.content
.insert(content_type.as_ref().to_string(), content);
pub fn with_content<S: AsRef<str>, C: Into<Component>>(
mut self,
content_type: S,
component: C,
) -> Self {
self.content.insert(
content_type.as_ref().to_string(),
Content::new(component.into()),
);

self
}
}

#[derive(Serialize, Deserialize, Default)]
#[non_exhaustive]
pub struct Content {
pub schema: Component,
}

impl Content {
pub fn new<I: Into<Component>>(schema: I) -> Self {
Self {
schema: schema.into(),
}
}
}
33 changes: 30 additions & 3 deletions src/openapi/response.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use std::collections::HashMap;
use std::collections::{BTreeMap, HashMap};

use serde::{Deserialize, Serialize};

use super::{header::Header, Component, Content};

#[non_exhaustive]
#[derive(Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct Responses {
#[serde(flatten)]
pub inner: HashMap<String, Response>,
pub inner: BTreeMap<String, Response>,
}

impl Responses {
Expand All @@ -26,14 +28,39 @@ impl Responses {
#[derive(Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct Response {
// TODO add missing fields
pub description: String,

#[serde(skip_serializing_if = "HashMap::is_empty")]
pub headers: HashMap<String, Header>,

#[serde(skip_serializing_if = "HashMap::is_empty")]
pub content: HashMap<String, Content>,
}

impl Response {
pub fn new<S: AsRef<str>>(description: S) -> Self {
Self {
description: description.as_ref().to_string(),
..Default::default()
}
}

pub fn with_content<C: Into<Component>, S: AsRef<str>>(
mut self,
content_type: S,
component: C,
) -> Self {
self.content.insert(
content_type.as_ref().to_string(),
Content::new(component.into()),
);

self
}

pub fn with_header<S: AsRef<str>>(mut self, name: S, header: Header) -> Self {
self.headers.insert(name.as_ref().to_string(), header);

self
}
}
20 changes: 10 additions & 10 deletions tests/path_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ macro_rules! test_api_fn {
mod $module {
$( $(#[$meta])* )*
#[utoipa::path(
$operation,
$( operation_id = $operation_id, )*
path = $path,
responses = [
(200, "success", String),
],
$( params = $params, )*
$( tag = $tag, )*
)]
$operation,
$( operation_id = $operation_id, )*
path = $path,
responses = [
(status = 200, description = "success response")
],
$( params = $params, )*
$( tag = $tag, )*
)]
#[allow(unused)]
async fn $name() -> String {
"foo".to_string()
Expand Down Expand Up @@ -153,7 +153,7 @@ fn derive_path_with_defaults_success() {
get,
path = "/foo/{id}",
responses = [
(200, "success", String)
(status = 200, description = "success response")
],
params = [
("id" = u64, description = "Foo database id"),
Expand Down
8 changes: 4 additions & 4 deletions tests/path_derive_actix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ mod mod_derive_path_actix {
/// Get foo by id long description
#[utoipa::path(
responses = [
(200, "success", String),
(status = 200, description = "success response")
],
params = [
("id", description = "Foo id"),
Expand Down Expand Up @@ -57,7 +57,7 @@ mod mod_derive_path_unnamed_regex_actix {
/// Get foo by id long description
#[utoipa::path(
responses = [
(200, "success", String),
(status = 200, description = "success"),
],
params = [
("arg0", description = "Foo path unnamed regex tail")
Expand Down Expand Up @@ -100,7 +100,7 @@ mod mod_derive_path_named_regex_actix {
/// Get foo by id long description
#[utoipa::path(
responses = [
(200, "success", String),
(status = 200, description = "success response")
],
params = [
("tail", description = "Foo path named regex tail")
Expand Down Expand Up @@ -143,7 +143,7 @@ macro_rules! test_derive_path_operations {

#[utoipa::path(
responses = [
(200, "success", String),
(status = 200, description = "success response")
]
)]
#[$operation("/foo")]
Expand Down
6 changes: 3 additions & 3 deletions tests/path_parameter_derive_actix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ mod derive_params_multiple_actix {
get,
path = "/foo/{id}/{digest}",
responses = [
(200, "success", String),
(status = 200, description = "success response")
],
params = [
("id", description = "Foo id"),
Expand Down Expand Up @@ -68,7 +68,7 @@ mod derive_parameters_multiple_no_matching_names_actix {
get,
path = "/foo/{id}/{digest}",
responses = [
(200, "success", String),
(status = 200, description = "success response")
],
params = [
("id" = i32, description = "Foo id"),
Expand Down Expand Up @@ -119,7 +119,7 @@ mod derive_params_from_method_args_actix {
get,
path = "/foo/{id}/{digest}",
responses = [
(200, "success", String),
(status = 200, description = "success response")
],
)]
#[allow(unused)]
Expand Down
10 changes: 5 additions & 5 deletions tests/path_parameter_derive_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ mod derive_params_all_options {
get,
path = "/foo/{id}",
responses = [
(200, "success", String),
(status = 200, description = "success"),
],
params = [
("id" = i32, path, required, deprecated, description = "Search foos by ids"),
Expand Down Expand Up @@ -55,7 +55,7 @@ mod derive_params_minimal {
get,
path = "/foo/{id}",
responses = [
(200, "success", String),
(status = 200, description = "success"),
],
params = [
("id" = i32, description = "Search foos by ids"),
Expand Down Expand Up @@ -96,7 +96,7 @@ mod derive_params_multiple {
get,
path = "/foo/{id}/{digest}",
responses = [
(200, "success", String),
(status = 200, description = "success"),
],
params = [
("id" = i32, description = "Foo id"),
Expand Down Expand Up @@ -146,7 +146,7 @@ mod mod_derive_parameters_all_types {
get,
path = "/foo/{id}",
responses = [
(200, "success", String),
(status = 200, description = "success"),
],
params = [
("id" = i32, path, description = "Foo id"),
Expand Down Expand Up @@ -222,7 +222,7 @@ mod derive_params_without_args {
get,
path = "/foo/{id}",
responses = [
(200, "success", String),
(status = 200, description = "success"),
],
params = [
("id" = i32, path, description = "Foo id"),
Expand Down
Loading

0 comments on commit b7b37b4

Please sign in to comment.