elif_http/routing/
mod.rs

1//! HTTP routing system for elif.rs
2//!
3//! This module provides flexible HTTP routing with:
4//! - Framework-independent route pattern matching
5//! - Advanced parameter extraction with type conversion
6//! - Route compilation and optimization
7//! - Efficient route resolution
8//! - Route groups and prefixes
9//! - Route naming and URL generation
10//! - Parameter validation and constraints
11
12// Legacy modules (will be refactored to use new engine)
13pub mod params;
14pub mod router;
15pub mod group;
16pub mod versioned;
17
18// New framework-independent routing engine
19pub mod pattern;
20pub mod matcher;
21pub mod extraction;
22pub mod compiler;
23
24// Legacy exports (for backward compatibility)
25pub use router::{Router as ElifRouter, Router, RouteBuilder};
26pub use params::{PathParams, RouteParam, ParamError, ParamType};
27pub use group::{RouteGroup, GroupBuilder};
28pub use versioned::{VersionedRouter, VersionedRouteBuilder, versioned_router, path_versioned_router, header_versioned_router};
29
30// New engine exports
31pub use pattern::{RoutePattern, PathSegment, ParamConstraint, CompiledRoute, RouteMatch};
32pub use matcher::{RouteMatcher, RouteDefinition, MatcherStats, RouteMatcherBuilder};
33pub use extraction::{ParameterExtractor, ExtractedParams, TypedExtractorBuilder, ExtractionError};
34pub use compiler::{RouteCompiler, CompilableRoute, CompilationResult, CompilationStats, RouteCompilerBuilder};
35
36use axum::http::Method;
37use std::collections::HashMap;
38use serde::{Serialize, Deserialize};
39
40/// HTTP methods supported by the router
41#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
42pub enum HttpMethod {
43    GET,
44    POST,
45    PUT,
46    DELETE,
47    PATCH,
48    HEAD,
49    OPTIONS,
50    TRACE,
51}
52
53impl std::fmt::Display for HttpMethod {
54    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55        match self {
56            HttpMethod::GET => write!(f, "GET"),
57            HttpMethod::POST => write!(f, "POST"),
58            HttpMethod::PUT => write!(f, "PUT"),
59            HttpMethod::DELETE => write!(f, "DELETE"),
60            HttpMethod::PATCH => write!(f, "PATCH"),
61            HttpMethod::HEAD => write!(f, "HEAD"),
62            HttpMethod::OPTIONS => write!(f, "OPTIONS"),
63            HttpMethod::TRACE => write!(f, "TRACE"),
64        }
65    }
66}
67
68impl From<Method> for HttpMethod {
69    fn from(method: Method) -> Self {
70        match method {
71            Method::GET => HttpMethod::GET,
72            Method::POST => HttpMethod::POST,
73            Method::PUT => HttpMethod::PUT,
74            Method::DELETE => HttpMethod::DELETE,
75            Method::PATCH => HttpMethod::PATCH,
76            Method::HEAD => HttpMethod::HEAD,
77            Method::OPTIONS => HttpMethod::OPTIONS,
78            Method::TRACE => HttpMethod::TRACE,
79            _ => HttpMethod::GET, // Default fallback
80        }
81    }
82}
83
84impl From<HttpMethod> for Method {
85    fn from(method: HttpMethod) -> Self {
86        match method {
87            HttpMethod::GET => Method::GET,
88            HttpMethod::POST => Method::POST,
89            HttpMethod::PUT => Method::PUT,
90            HttpMethod::DELETE => Method::DELETE,
91            HttpMethod::PATCH => Method::PATCH,
92            HttpMethod::HEAD => Method::HEAD,
93            HttpMethod::OPTIONS => Method::OPTIONS,
94            HttpMethod::TRACE => Method::TRACE,
95        }
96    }
97}
98
99/// Route metadata for introspection and URL generation
100#[derive(Debug, Clone, Serialize, Deserialize)]
101pub struct RouteInfo {
102    pub name: Option<String>,
103    pub path: String,
104    pub method: HttpMethod,
105    pub params: Vec<String>,
106    pub group: Option<String>,
107}
108
109/// Route registry for managing all registered routes
110#[derive(Debug, Default)]
111pub struct RouteRegistry {
112    routes: HashMap<String, RouteInfo>,
113    named_routes: HashMap<String, String>, // name -> route_id
114}
115
116impl RouteRegistry {
117    pub fn new() -> Self {
118        Self {
119            routes: HashMap::new(),
120            named_routes: HashMap::new(),
121        }
122    }
123
124    pub fn register(&mut self, route_id: String, info: RouteInfo) {
125        if let Some(ref name) = info.name {
126            self.named_routes.insert(name.clone(), route_id.clone());
127        }
128        self.routes.insert(route_id, info);
129    }
130
131    pub fn get(&self, route_id: &str) -> Option<&RouteInfo> {
132        self.routes.get(route_id)
133    }
134
135    pub fn get_by_name(&self, name: &str) -> Option<&RouteInfo> {
136        self.named_routes.get(name)
137            .and_then(|id| self.routes.get(id))
138    }
139
140    pub fn all_routes(&self) -> &HashMap<String, RouteInfo> {
141        &self.routes
142    }
143}