Skip to content

Commit

Permalink
Merge branch 'master' into feat/#124
Browse files Browse the repository at this point in the history
  • Loading branch information
myyrakle committed Aug 25, 2024
2 parents 5554911 + 6a7d0e3 commit 53918b2
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 16 deletions.
8 changes: 2 additions & 6 deletions rupring/src/example/domains/users/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,23 +62,19 @@ pub fn create_user(request: rupring::Request, _: rupring::Response) -> rupring::
#[rupring::Put(path = /users/:id)]
#[tags = [user]]
#[summary = "user 정보 수정"]
#[params = crate::domains::users::dto::UpdateUserRequest]
pub fn update_user(
request: rupring::Request,
#[path = "id"]
#[desc = "user 고유 id"]
#[required]
id: i32,
) -> rupring::Response {
let user_service = request.get_provider::<Arc<dyn IUserService>>().unwrap();

let request = serde_json::from_str(&request.body);

let mut request: UpdateUserRequest = match request {
let request: UpdateUserRequest = match request {
Ok(request) => request,
Err(_) => return rupring::Response::new().status(400).text("bad request"),
};

request.id = id;

let response = user_service.update_user(request);

Expand Down
5 changes: 4 additions & 1 deletion rupring/src/example/domains/users/dto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,12 @@ pub struct CreateUserRequest {
#[derive(Debug, Serialize, Deserialize)]
pub struct CreateUserResponse {}

#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize, RupringDoc)]
pub struct UpdateUserRequest {
#[serde(skip_serializing)]
#[path_param = "id"]
#[desc = "user 고유 id"]
#[required]
pub id: i32,
pub username: String,
pub email: String,
Expand Down
2 changes: 1 addition & 1 deletion rupring/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ pub trait IRoute {
Default::default()
}

fn swagger_request_body(&self) -> Option<SwaggerRequestBody> {
fn swagger_request_info(&self) -> Option<SwaggerRequestBody> {
None
}
}
Expand Down
8 changes: 7 additions & 1 deletion rupring/src/swagger/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ fn generate_swagger(swagger: &mut SwaggerSchema, root_module: Box<dyn crate::IMo
let normalized_path = swaggerize_url(normalized_path.as_str());
let mut operation = route.swagger();

if let Some(swagger_request_body) = route.swagger_request_body() {
let request_info = route.swagger_request_info();

if let Some(swagger_request_body) = request_info {
operation.parameters.push(SwaggerParameter {
name: swagger_request_body
.definition_name
Expand Down Expand Up @@ -86,6 +88,10 @@ fn generate_swagger(swagger: &mut SwaggerSchema, root_module: Box<dyn crate::IMo
dependency.definition_value,
);
}

for swagger_parameter in swagger_request_body.path_parameters {
operation.parameters.push(swagger_parameter);
}
}

// TODO: 추후에는 swagger ignore 속성을 추가해서 그걸로 처리
Expand Down
6 changes: 6 additions & 0 deletions rupring/src/swagger/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,12 @@ pub struct SwaggerDefinitionObject {

#[serde(rename = "required")]
pub required: Vec<String>,

#[serde(skip_serializing)]
pub path_parameters: Vec<SwaggerParameter>,

#[serde(skip_serializing)]
pub query_parameters: Vec<SwaggerParameter>,
}

pub type SwaggerProperties = HashMap<String, SwaggerProperty>;
Expand Down
21 changes: 17 additions & 4 deletions rupring/src/swagger/macros.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
use std::collections::HashMap;

use super::{
SwaggerArrayProperty, SwaggerDefinition, SwaggerDefinitionObject, SwaggerReference,
SwaggerSingleProperty, SwaggerType, SwaggerTypeOrReference,
SwaggerArrayProperty, SwaggerDefinition, SwaggerDefinitionObject, SwaggerParameter,
SwaggerReference, SwaggerSingleProperty, SwaggerType, SwaggerTypeOrReference,
};

pub struct SwaggerRequestInfo {
pub request_body: Option<SwaggerRequestBody>,
pub path_parameters: Vec<SwaggerParameter>,
pub query_parameters: Vec<SwaggerParameter>,
}

pub struct SwaggerDefinitionContext {
pub definitions: HashMap<String, SwaggerDefinitionObject>,
}
Expand Down Expand Up @@ -188,9 +194,12 @@ pub struct SwaggerRequestBody {
pub definition_value: SwaggerDefinitionObject,

pub dependencies: Vec<SwaggerRequestBody>,

pub path_parameters: Vec<SwaggerParameter>,
pub query_parameters: Vec<SwaggerParameter>,
}

pub fn generate_swagger_request_body<T: ToSwaggerDefinitionNode>() -> Option<SwaggerRequestBody> {
pub fn generate_swagger_request_info<T: ToSwaggerDefinitionNode>() -> Option<SwaggerRequestBody> {
let mut context = SwaggerDefinitionContext {
definitions: Default::default(),
};
Expand All @@ -202,8 +211,10 @@ pub fn generate_swagger_request_body<T: ToSwaggerDefinitionNode>() -> Option<Swa
if let crate::swagger::macros::SwaggerDefinitionNode::Object(def) = root_definition {
let swagger_request_body = SwaggerRequestBody {
definition_name: root_definition_name,
definition_value: def,
definition_value: def.clone(),
dependencies: vec![],
path_parameters: def.path_parameters.clone(),
query_parameters: def.query_parameters.clone(),
};

swagger_request_body
Expand All @@ -216,6 +227,8 @@ pub fn generate_swagger_request_body<T: ToSwaggerDefinitionNode>() -> Option<Swa
definition_name: name,
definition_value: definition,
dependencies: vec![],
path_parameters: vec![],
query_parameters: vec![],
});
}

Expand Down
52 changes: 49 additions & 3 deletions rupring_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,8 +427,8 @@ fn MapRoute(method: String, attr: TokenStream, item: TokenStream) -> TokenStream
if request_body.len() > 0 {
swagger_request_body_code = format!(
r#"
fn swagger_request_body(&self) -> Option<rupring::swagger::macros::SwaggerRequestBody> {{
rupring::swagger::macros::generate_swagger_request_body::<{request_body}>()
fn swagger_request_info(&self) -> Option<rupring::swagger::macros::SwaggerRequestBody> {{
rupring::swagger::macros::generate_swagger_request_info::<{request_body}>()
}}
"#
);
Expand Down Expand Up @@ -543,7 +543,18 @@ pub fn PatchMapping(attr: TokenStream, item: TokenStream) -> TokenStream {

#[proc_macro_derive(
RupringDoc,
attributes(example, description, desc, required, name, path, query, body)
attributes(
example,
description,
desc,
required,
name,
path_param,
param,
query,
body,
ignore,
)
)]
pub fn derive_rupring_doc(item: TokenStream) -> TokenStream {
let ast = syn::parse_macro_input!(item as syn::ItemStruct);
Expand All @@ -568,6 +579,8 @@ pub fn derive_rupring_doc(item: TokenStream) -> TokenStream {
code += format!(r#"type_: "object".to_string(),"#).as_str();
code += format!(r#"properties: std::collections::HashMap::new(),"#).as_str();
code += format!(r#"required: vec![],"#).as_str();
code += format!(r#"path_parameters: vec![],"#).as_str();
code += format!(r#"query_parameters: vec![],"#).as_str();
code += "};";

for field in ast.fields.iter() {
Expand All @@ -580,6 +593,9 @@ pub fn derive_rupring_doc(item: TokenStream) -> TokenStream {
let attributes = field.attrs.clone();

let mut is_required = true;
let mut is_ignore = false;

let mut is_path_parameter = false;

if field_type.starts_with("Option<") {
is_required = false;
Expand Down Expand Up @@ -633,12 +649,22 @@ pub fn derive_rupring_doc(item: TokenStream) -> TokenStream {
field_name = text;
}
}
"path_param" | "param" => {
is_path_parameter = true;
}
"ignore" => {
is_ignore = true;
}
_ => {}
}
}
}
}

if is_ignore {
continue;
}

if is_required {
code += format!(r#"swagger_definition.required.push("{field_name}".to_string());"#)
.as_str();
Expand All @@ -649,6 +675,26 @@ pub fn derive_rupring_doc(item: TokenStream) -> TokenStream {
field_type = field_type.replace("<", "::<")
}

if is_path_parameter {
code += format!(
r#"swagger_definition.path_parameters.push(rupring::swagger::json::SwaggerParameter {{
name: "{field_name}".to_string(),
in_: rupring::swagger::json::SwaggerParameterCategory::Path,
description: "{description}".to_string(),
required: {is_required},
schema: Some(rupring::swagger::json::SwaggerTypeOrReference::Type(
rupring::swagger::json::SwaggerType {{
type_: "{field_type}".to_string(),
}}
)),
type_: None,
}});"#
).as_str();

continue;
}

// Body 파라미터 생성 구현
code += format!(r#"let property_of_type = {field_type}::to_swagger_definition(context);"#)
.as_str();

Expand Down

0 comments on commit 53918b2

Please sign in to comment.