Skip to content

Commit

Permalink
[#15] body bind 및 path param bind 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
myyrakle committed Aug 26, 2024
1 parent 11da7e1 commit 4c6409f
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 0 deletions.
1 change: 1 addition & 0 deletions rupring/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,5 +619,6 @@ impl<T: IModule + Clone + Copy + Sync + Send + 'static> RupringFactory<T> {
#[cfg(test)]
mod test_proc_macro;

pub use anyhow;
pub use serde;
pub use serde_json;
6 changes: 6 additions & 0 deletions rupring/src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ pub struct Request {
pub(crate) di_context: Arc<crate::DIContext>,
}

pub trait BindFromRequest {
fn bind(&mut self, request: Request) -> anyhow::Result<Self>
where
Self: Sized;
}

impl UnwindSafe for Request {}

impl Request {
Expand Down
49 changes: 49 additions & 0 deletions rupring_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,10 @@ pub fn derive_rupring_doc(item: TokenStream) -> TokenStream {
format!(r#"#[derive(rupring::serde::Serialize, rupring::serde::Deserialize)]"#).as_str();
define_struct_for_json += format!(r#"pub struct {struct_name}__JSON {{"#).as_str();

let mut json_field_names = vec![];
let mut path_field_names = vec![];
let mut query_field_names = vec![];

for field in ast.fields.iter() {
let mut description = "".to_string();
let mut example = r#""""#.to_string();
Expand Down Expand Up @@ -759,6 +763,8 @@ pub fn derive_rupring_doc(item: TokenStream) -> TokenStream {
}

if is_path_parameter {
path_field_names.push(field_name.clone());

code += format!(
r#"swagger_definition.path_parameters.push(rupring::swagger::json::SwaggerParameter {{
name: "{field_name}".to_string(),
Expand All @@ -778,6 +784,8 @@ pub fn derive_rupring_doc(item: TokenStream) -> TokenStream {
}

if is_query_parameter {
query_field_names.push(field_name.clone());

code += format!(
r#"swagger_definition.query_parameters.push(rupring::swagger::json::SwaggerParameter {{
name: "{field_name}".to_string(),
Expand All @@ -796,6 +804,8 @@ pub fn derive_rupring_doc(item: TokenStream) -> TokenStream {
continue;
}

json_field_names.push(field_name.clone());

define_struct_for_json += format!(
r#"
pub {field_name}: {field_type},
Expand Down Expand Up @@ -853,5 +863,44 @@ pub fn derive_rupring_doc(item: TokenStream) -> TokenStream {

code += define_struct_for_json.as_str();

let mut request_bind_code = "".to_string();
request_bind_code +=
format!(r#"impl rupring::request::BindFromRequest for {struct_name} {{"#).as_str();

request_bind_code +=
"fn bind(&mut self, request: rupring::request::Request) -> rupring::anyhow::Result<Self> {";
request_bind_code += "use rupring::ParamStringDeserializer;";

request_bind_code += format!("let mut json_bound = rupring::serde_json::from_str::<{struct_name}__JSON>(request.body.as_str())?;").as_str();

request_bind_code += format!("let mut bound = {struct_name} {{").as_str();

for field_name in json_field_names {
request_bind_code += format!("{field_name}: json_bound.{field_name},").as_str();
}

for field_name in path_field_names {
request_bind_code += format!(
r#"{field_name}: rupring::ParamString(
request.path_parameters["{field_name}"].clone()
).
deserialize().
map_err(
|_|Err(rupring::anyhow::anyhow!("{field_name} is invalid"))
)?,
"#
)
.as_str();
}

request_bind_code += format!("}};").as_str();

request_bind_code += "Ok(bound)";
request_bind_code += "}";

request_bind_code += format!(r#"}}"#).as_str();

code += request_bind_code.as_str();

return TokenStream::from_str(code.as_str()).unwrap();
}

0 comments on commit 4c6409f

Please sign in to comment.