awesome_operates/router/
handler.rs1use axum::body::Body;
2use axum::extract::Request;
3use axum::Json;
4use serde_json::Value;
5
6#[macro_export]
7macro_rules! method_exchange {
8 ($method:expr, $path:expr, $resp:expr) => {
9 match $method.to_lowercase().as_str() {
10 "get" => $crate::build_method_router!(get, $path, $resp),
11 "post" => $crate::build_method_router!(post, $path, $resp),
12 "delete" => $crate::build_method_router!(delete, $path, $resp),
13 "put" => $crate::build_method_router!(put, $path, $resp),
14 "patch" => $crate::build_method_router!(patch, $path, $resp),
15 _ => $crate::build_method_router!(get, $path, $resp),
16 }
17 };
18}
19
20#[macro_export]
21macro_rules! build_method_router {
22 ($method:ident, $path:expr, $resp:expr) => {
23 axum::routing::$method(|req: axum::extract::Request<axum::body::Body>| async move {
24 $crate::router::handler::handle_openapi_request(req, $resp).await
25 })
26 };
27}
28
29pub async fn handle_openapi_request(req: Request<Body>, mut resp: Value) -> Json<Value> {
30 let (parts, body) = req.into_parts();
31 let bytes = http_body_util::BodyExt::collect(body)
32 .await
33 .unwrap()
34 .to_bytes();
35 tracing::debug!("handle openapi request receive body len {}", bytes.len());
36 let json_body = serde_json::from_slice(&bytes).unwrap_or_else(|_| {
37 tracing::info!("body transfer is not json for {bytes:?}");
38 serde_json::json!({})
39 });
40 resp["request"] = serde_json::json!({
41 "method": parts.method.as_str(),
42 "path": parts.uri.to_string(),
43 "body": json_body
44 });
45 resp["url_args"] = match_url_openapi_path(
46 resp["path_with_prefix"].as_str().unwrap_or_default(),
47 &parts.uri.to_string(),
48 );
49 resp["body_match_list"] = match_body_args(&resp["component"], &json_body);
50 Json(resp)
51}
52
53pub fn match_url_openapi_path(openapi: &str, path: &str) -> Value {
57 let mut resp = serde_json::json!({});
58 if let Some(openapi) = openapi.split('?').next() {
59 if let Some(path) = path.split('?').next() {
60 let openapi_splits = openapi.split('/').collect::<Vec<&str>>();
61 let path_splits = path.split('/').collect::<Vec<&str>>();
62 for (i, s) in openapi_splits.iter().enumerate() {
63 if s.starts_with(':') {
64 resp[s.replace(':', "")] = serde_json::json!(path_splits.get(i));
65 }
66 }
67 }
68 }
69 serde_json::json!(resp)
70}
71
72pub fn match_body_args(component: &Value, body: &Value) -> Value {
74 tracing::debug!("match body with {body}");
75 let mut resp = vec![];
76 if let Some(properties) = component["properties"].as_object() {
77 for (key, value) in properties.iter() {
78 let body_value = &body[key];
79 if !body_value.is_null() {
80 resp.push(serde_json::json!({
81 "key": key,
82 "value": body_value,
83 "description": value["description"],
84 "type": value["type"]
85 }))
86 }
87 }
88 }
89 serde_json::json!(resp)
90}