bytedocs_rs/parser/
warp.rs

1use crate::core::types::{RouteInfo, Parameter, RequestBody, Response};
2use crate::parser::common::{HandlerInfo, FrameworkParser, extract_path_params, generate_default_responses, normalize_method};
3use std::collections::HashMap;
4use std::any::Any;
5
6pub struct WarpParser;
7
8impl WarpParser {
9    pub fn new() -> Self {
10        Self
11    }
12
13    pub fn create_route_info(
14        &self,
15        method: &str,
16        path: &str,
17        handler_info: HandlerInfo,
18    ) -> RouteInfo {
19        let path_params = extract_path_params(path);
20        let mut all_params = path_params;
21        all_params.extend(handler_info.parameters);
22
23        RouteInfo {
24            method: normalize_method(method),
25            path: path.to_string(),
26            handler: Box::new(()),
27            middlewares: Vec::new(),
28            summary: if handler_info.summary.is_empty() {
29                None
30            } else {
31                Some(handler_info.summary)
32            },
33            description: if handler_info.description.is_empty() {
34                None
35            } else {
36                Some(handler_info.description)
37            },
38            parameters: if all_params.is_empty() {
39                None
40            } else {
41                Some(all_params)
42            },
43            request_body: None,
44            responses: Some(generate_default_responses()),
45        }
46    }
47
48    // Helper method to register Warp routes
49    pub fn register_route(
50        &self,
51        method: &str,
52        path: &str,
53        summary: Option<&str>,
54        description: Option<&str>,
55        parameters: Option<Vec<Parameter>>,
56        request_body: Option<RequestBody>,
57        responses: Option<HashMap<String, Response>>,
58    ) -> RouteInfo {
59        let handler_info = HandlerInfo {
60            summary: summary.unwrap_or("").to_string(),
61            description: description.unwrap_or("").to_string(),
62            parameters: parameters.unwrap_or_default(),
63        };
64
65        let mut route = self.create_route_info(method, path, handler_info);
66
67        if let Some(body) = request_body {
68            route.request_body = Some(body);
69        }
70
71        if let Some(resp) = responses {
72            route.responses = Some(resp);
73        }
74
75        route
76    }
77
78    // Warp-specific helpers
79    pub fn extract_warp_path_params(&self, path: &str) -> Vec<Parameter> {
80        // Warp uses different syntax for path parameters
81        let params = Vec::new();
82
83        // Extract parameters from warp::path syntax
84        // This is a simplified version - real implementation would be more complex
85        if path.contains("param()") {
86            // Would extract from warp::path::param() usage
87        }
88
89        params
90    }
91}
92
93impl FrameworkParser for WarpParser {
94    fn parse_routes(&self, _app: &dyn Any) -> Vec<RouteInfo> {
95        // Warp filters are composed dynamically, making introspection difficult
96        // Users would need to manually register routes
97        Vec::new()
98    }
99
100    fn extract_handler_info(&self, _handler: &dyn Any) -> HandlerInfo {
101        HandlerInfo {
102            summary: String::new(),
103            description: String::new(),
104            parameters: Vec::new(),
105        }
106    }
107}
108
109impl Default for WarpParser {
110    fn default() -> Self {
111        Self::new()
112    }
113}
114
115// Macro for Warp route registration
116#[macro_export]
117macro_rules! warp_route {
118    ($parser:expr, $method:expr, $path:expr, $filter:expr) => {
119        $parser.register_route($method, $path, None, None, None, None, None)
120    };
121    ($parser:expr, $method:expr, $path:expr, $filter:expr, summary = $summary:expr) => {
122        $parser.register_route($method, $path, Some($summary), None, None, None, None)
123    };
124}
125
126// Helper functions for common Warp patterns
127pub fn extract_warp_json_body<T>() -> Option<RequestBody>
128where
129    T: serde::Serialize + 'static,
130{
131    Some(RequestBody {
132        content_type: "application/json".to_string(),
133        schema: serde_json::json!({
134            "type": "object",
135            "description": format!("JSON body of type {}", std::any::type_name::<T>())
136        }),
137        example: None,
138        required: true,
139    })
140}