kotoba_handler/
integration.rs

1//! Integration with existing Kotoba crates
2//!
3//! このモジュールは既存のkotoba-jsonnetとkotoba-kotobasの機能を
4//! 統合的に利用する方法を提供します。
5
6use crate::error::{HandlerError, Result};
7use crate::types::{HandlerContext, HandlerResult};
8
9// Jsonnet integration removed - using kotobas only
10
11/// Integration with kotoba-kotobas for HTTP configuration
12#[cfg(feature = "kotobas")]
13pub mod kotobas_integration {
14    use super::*;
15    use kotoba_kotobas::http_parser::{HttpConfig, HttpRouteConfig, HttpMethod};
16
17    /// Kotobas HTTP configuration handler
18    pub struct KotobasHttpHandler {
19        config: HttpConfig,
20    }
21
22    impl KotobasHttpHandler {
23        pub fn new(config_content: &str) -> Result<Self> {
24            // Parse Kotobas HTTP configuration
25            let config: HttpConfig = serde_json::from_str(config_content)
26                .map_err(|e| HandlerError::Parse(format!("Failed to parse HTTP config: {}", e)))?;
27
28            Ok(Self { config })
29        }
30
31        /// Find matching route for request
32        pub fn find_route(&self, method: &str, path: &str) -> Option<&HttpRouteConfig> {
33            let request_method = match method {
34                "GET" => HttpMethod::GET,
35                "POST" => HttpMethod::POST,
36                "PUT" => HttpMethod::PUT,
37                "DELETE" => HttpMethod::DELETE,
38                "PATCH" => HttpMethod::PATCH,
39                "OPTIONS" => HttpMethod::OPTIONS,
40                "HEAD" => HttpMethod::HEAD,
41                _ => return None,
42            };
43
44            self.config.routes.iter()
45                .find(|route| route.method == request_method && route.path == path)
46        }
47
48        /// Get middleware for route
49        pub fn get_middleware(&self, route: &HttpRouteConfig) -> Vec<String> {
50            route.middleware.clone()
51        }
52    }
53}
54
55/// Combined handler that integrates Kotobas functionality
56#[cfg(feature = "kotobas")]
57pub struct IntegratedHandler {
58    kotobas_handler: kotobas_integration::KotobasHttpHandler,
59}
60
61#[cfg(feature = "kotobas")]
62impl IntegratedHandler {
63    /// Create new integrated handler
64    pub fn new(kotobas_config: &str) -> Result<Self> {
65        Ok(Self {
66            kotobas_handler: kotobas_integration::KotobasHttpHandler::new(kotobas_config)?,
67        })
68    }
69
70    /// Process request with integrated handlers
71    pub async fn process_request(&mut self, context: HandlerContext, _content: Option<&str>) -> Result<String> {
72        // Find matching route in Kotobas configuration
73        if let Some(route) = self.kotobas_handler.find_route(&context.method, &context.path) {
74            // Apply middleware
75            let middleware = self.kotobas_handler.get_middleware(route);
76
77            // Return route handler info
78            Ok(format!(
79                "Route matched: {} {} -> Handler: {}",
80                route.method.as_ref(),
81                route.path,
82                route.handler
83            ))
84        } else {
85            Ok("No route matched".to_string())
86        }
87    }
88}
89
90/// Factory function to create appropriate handler based on content type
91#[cfg(feature = "kotobas")]
92pub fn create_handler(content: &str, _context: &HandlerContext) -> Result<Box<dyn HandlerTrait>> {
93    if serde_json::from_str::<serde_json::Value>(content).is_ok() {
94        // JSON content - use Kotobas handler
95        let handler = kotobas_integration::KotobasHttpHandler::new(content)?;
96        Ok(Box::new(KotobasWrapper(handler)))
97    } else {
98        Err(HandlerError::Parse("Unsupported content format - only JSON/Kotobas supported".to_string()))
99    }
100}
101
102/// Handler trait for unified interface
103pub trait HandlerTrait {
104    fn process(&mut self, context: HandlerContext) -> Result<String>;
105}
106
107// Wrapper implementations
108#[cfg(feature = "kotobas")]
109struct KotobasWrapper(kotobas_integration::KotobasHttpHandler);
110
111#[cfg(feature = "kotobas")]
112impl HandlerTrait for KotobasWrapper {
113    fn process(&mut self, context: HandlerContext) -> Result<String> {
114        match self.0.find_route(&context.method, &context.path) {
115            Some(route) => Ok(format!(
116                "Kotobas route: {} {} -> {}",
117                route.method.as_ref(),
118                route.path,
119                route.handler
120            )),
121            None => Ok("No Kotobas route matched".to_string()),
122        }
123    }
124}