bytedocs_rs/parser/
common.rs1use crate::core::types::{Parameter, RouteInfo, Response};
7use regex::Regex;
8use std::collections::HashMap;
9
10#[derive(Debug, Clone)]
12pub struct HandlerInfo {
13 pub summary: String,
14 pub description: String,
15 pub parameters: Vec<Parameter>,
16}
17
18pub fn extract_path_params(path: &str) -> Vec<Parameter> {
26 let mut params = Vec::new();
27
28 let colon_regex = Regex::new(r":(\w+)").unwrap();
30 for cap in colon_regex.captures_iter(path) {
31 if let Some(param_name) = cap.get(1) {
32 params.push(Parameter {
33 name: param_name.as_str().to_string(),
34 r#in: "path".to_string(),
35 r#type: "string".to_string(),
36 required: true,
37 description: String::new(),
38 example: None,
39 });
40 }
41 }
42
43 let brace_regex = Regex::new(r"\{(\w+)\}").unwrap();
45 for cap in brace_regex.captures_iter(path) {
46 if let Some(param_name) = cap.get(1) {
47 params.push(Parameter {
48 name: param_name.as_str().to_string(),
49 r#in: "path".to_string(),
50 r#type: "string".to_string(),
51 required: true,
52 description: String::new(),
53 example: None,
54 });
55 }
56 }
57
58 params
59}
60
61pub fn parse_handler_comments(comments: &[String]) -> HandlerInfo {
69 let mut info = HandlerInfo {
70 summary: String::new(),
71 description: String::new(),
72 parameters: Vec::new(),
73 };
74
75 let param_regex = Regex::new(r#"@param\s+(\w+)\s+(\w+)\s+(\w+)\s+(true|false)\s+"([^"]*)""#).unwrap();
77
78 for line in comments {
79 if let Some(caps) = param_regex.captures(line) {
80 let param = Parameter {
81 name: caps[1].to_string(),
82 r#in: caps[2].to_string(),
83 r#type: caps[3].to_string(),
84 required: &caps[4] == "true",
85 description: caps[5].to_string(),
86 example: None,
87 };
88 info.parameters.push(param);
89 } else if line.starts_with("@summary") {
90 info.summary = line.strip_prefix("@summary").unwrap_or("").trim().to_string();
91 } else if line.starts_with("@description") {
92 info.description = line.strip_prefix("@description").unwrap_or("").trim().to_string();
93 } else if info.summary.is_empty() && !line.trim().is_empty() {
94 info.summary = line.trim().to_string();
96 }
97 }
98
99 info
100}
101
102pub fn normalize_method(method: &str) -> String {
104 method.to_uppercase()
105}
106
107pub fn generate_default_responses() -> HashMap<String, Response> {
111 let mut responses = HashMap::new();
112
113 responses.insert("200".to_string(), Response {
114 description: "OK".to_string(),
115 example: Some(serde_json::json!({"status": "success"})),
116 schema: None,
117 content_type: Some("application/json".to_string()),
118 });
119
120 responses.insert("400".to_string(), Response {
121 description: "Bad Request".to_string(),
122 example: None,
123 schema: None,
124 content_type: Some("application/json".to_string()),
125 });
126
127 responses.insert("404".to_string(), Response {
128 description: "Not Found".to_string(),
129 example: None,
130 schema: None,
131 content_type: Some("application/json".to_string()),
132 });
133
134 responses.insert("500".to_string(), Response {
135 description: "Internal Server Error".to_string(),
136 example: None,
137 schema: None,
138 content_type: Some("application/json".to_string()),
139 });
140
141 responses
142}
143
144pub trait FrameworkParser {
146 fn parse_routes(&self, app: &dyn std::any::Any) -> Vec<RouteInfo>;
147 fn extract_handler_info(&self, handler: &dyn std::any::Any) -> HandlerInfo;
148}