module hono import net.urllib import net.http import time // Context 路由器 struct ContextRouter { mut: handlers struct { mut: get []IHandler post []IHandler put []IHandler delete []IHandler patch []IHandler head []IHandler options []IHandler } } // NotFound 处理器类型 pub type NotFoundHandler = fn (mut c Context) http.Response // Error 处理器类型 - 使用简单的错误信息和状态码 pub type ErrorHandler = fn (error_msg string, status_code int, mut c Context) http.Response pub struct Hono { mut: server http.Server = http.Server{} routes map[string] Hono = {} base_path string not_found_handler ?NotFoundHandler // 自定义 404 处理器 error_handler ?ErrorHandler // 自定义错误处理器 pub mut: context_router ContextRouter = ContextRouter{} context_hybrid_router ContextHybridRouter context_trie_router ContextTrieRouter fast_router FastRouter // 新增:快速路由器 use_fast_router bool = true // 新增:是否使用快速路由器 context_middlewares []ContextMiddleware route_middlewares map[string][]ContextMiddleware // 路由前缀对应的中间件 } // Context 中间件类型 type ContextMiddleware = fn (mut c Context, next fn (mut Context) http.Response) http.Response // Context 接口方法 pub fn (mut app Hono) get(path string, handler fn (mut Context) http.Response) { h := ContextHandler{ path: path handler: handler } // 添加到快速路由器 if app.use_fast_router { app.fast_router.add_route('GET', h, '') or { println('[WARNING] FastRouter failed to add route ${path}, falling back to hybrid router') app.context_hybrid_router.add_route('GET', h, '') } } else { app.context_hybrid_router.add_route('GET', h, '') } app.context_trie_router.add_route('GET', path, h) app.context_router.handlers.get << h } pub fn (mut app Hono) post(path string, handler fn (mut Context) http.Response) { h := ContextHandler{ path: path handler: handler } // 添加到快速路由器 if app.use_fast_router { app.fast_router.add_route('POST', h, '') or { println('[WARNING] FastRouter failed to add route ${path}, falling back to hybrid router') app.context_hybrid_router.add_route('POST', h, '') } } else { app.context_hybrid_router.add_route('POST', h, '') } app.context_trie_router.add_route('POST', path, h) app.context_router.handlers.post << h } pub fn (mut app Hono) put(path string, handler fn (mut Context) http.Response) { h := ContextHandler{path, handler} // 添加到快速路由器 if app.use_fast_router { app.fast_router.add_route('PUT', h, app.base_path) or { println('[WARNING] FastRouter failed to add route ${path}, falling back to hybrid router') app.context_hybrid_router.add_route('PUT', h, app.base_path) } } else { app.context_hybrid_router.add_route('PUT', h, app.base_path) } app.context_router.handlers.put << h app.context_trie_router.add_route('PUT', path, h) } pub fn (mut app Hono) delete(path string, handler fn (mut Context) http.Response) { h := ContextHandler{path, handler} // 添加到快速路由器 if app.use_fast_router { app.fast_router.add_route('DELETE', h, app.base_path) or { println('[WARNING] FastRouter failed to add route ${path}, falling back to hybrid router') app.context_hybrid_router.add_route('DELETE', h, app.base_path) } } else { app.context_hybrid_router.add_route('DELETE', h, app.base_path) } app.context_router.handlers.delete << h app.context_trie_router.add_route('DELETE', path, h) } pub fn (mut app Hono) patch(path string, handler fn (mut Context) http.Response) { h := ContextHandler{path, handler} // 添加到快速路由器 if app.use_fast_router { app.fast_router.add_route('PATCH', h, app.base_path) or { println('[WARNING] FastRouter failed to add route ${path}, falling back to hybrid router') app.context_hybrid_router.add_route('PATCH', h, app.base_path) } } else { app.context_hybrid_router.add_route('PATCH', h, app.base_path) } app.context_router.handlers.patch << h app.context_trie_router.add_route('PATCH', path, h) } pub fn (mut app Hono) head(path string, handler fn (mut Context) http.Response) { h := ContextHandler{path, handler} // 添加到快速路由器 if app.use_fast_router { app.fast_router.add_route('HEAD', h, app.base_path) or { println('[WARNING] FastRouter failed to add route ${path}, falling back to hybrid router') app.context_hybrid_router.add_route('HEAD', h, app.base_path) } } else { app.context_hybrid_router.add_route('HEAD', h, app.base_path) } app.context_router.handlers.head << h app.context_trie_router.add_route('HEAD', path, h) } pub fn (mut app Hono) options(path string, handler fn (mut Context) http.Response) { h := ContextHandler{path, handler} // 添加到快速路由器 if app.use_fast_router { app.fast_router.add_route('OPTIONS', h, app.base_path) or { println('[WARNING] FastRouter failed to add route ${path}, falling back to hybrid router') app.context_hybrid_router.add_route('OPTIONS', h, app.base_path) } } else { app.context_hybrid_router.add_route('OPTIONS', h, app.base_path) } app.context_router.handlers.options << h app.context_trie_router.add_route('OPTIONS', path, h) } // all() 方法 - 为所有 HTTP 方法注册同一个处理器 pub fn (mut app Hono) all(path string, handler fn (mut Context) http.Response) { app.get(path, handler) app.post(path, handler) app.put(path, handler) app.delete(path, handler) app.patch(path, handler) app.head(path, handler) app.options(path, handler) } // Context 中间件 pub fn (mut app Hono) use(mw ContextMiddleware) { app.context_middlewares << mw } // notFound() - 自定义 404 处理器 pub fn (mut app Hono) not_found(handler NotFoundHandler) { app.not_found_handler = handler } // onError() - 自定义错误处理器 pub fn (mut app Hono) on_error(handler ErrorHandler) { app.error_handler = handler } struct ServerHanler { mut: app Hono } fn server_hanler_new(app Hono) ServerHanler { return ServerHanler{ app: app } } fn (mut s ServerHanler) handle(req http.Request) http.Response { url := urllib.parse(req.url) or { urllib.URL{ path: '/' } } // 解析 query raw_query := url.query().to_map() mut query_map := map[string]string{} for key, values in raw_query { if values.len > 0 { query_map[key] = values[0] } } // 尝试 Context 路由 // 优先使用快速路由器 if s.app.use_fast_router { if route_match := s.app.fast_router.match_route(req.method.str(), url.path) { // param 由路由匹配结果提供 param_map := route_match.params.clone() // body body := req.data // 构造 Context mut ctx := Context.new(req, param_map, query_map, body) // 获取该路径对应的中间件 middlewares := s.get_middlewares_for_path(url.path) // 洋葱模型递归执行中间件 return s.exec_context_middlewares_with_list(0, middlewares, mut ctx, fn [route_match] (mut c Context) http.Response { return route_match.handler.handle(mut c) }) } // 如果快速路由器没有匹配,回退到混合路由器 if route_match := s.app.context_hybrid_router.match_route(req.method.str(), url.path) { // param 由路由匹配结果提供 param_map := route_match.params.clone() // body body := req.data // 构造 Context mut ctx := Context.new(req, param_map, query_map, body) // 获取该路径对应的中间件 middlewares := s.get_middlewares_for_path(url.path) // 洋葱模型递归执行中间件 return s.exec_context_middlewares_with_list(0, middlewares, mut ctx, fn [route_match] (mut c Context) http.Response { return route_match.handler.handle(mut c) }) } } else { if route_match := s.app.context_hybrid_router.match_route(req.method.str(), url.path) { // param 由路由匹配结果提供 param_map := route_match.params.clone() // body body := req.data // 构造 Context mut ctx := Context.new(req, param_map, query_map, body) // 获取该路径对应的中间件 middlewares := s.get_middlewares_for_path(url.path) // 洋葱模型递归执行中间件 return s.exec_context_middlewares_with_list(0, middlewares, mut ctx, fn [route_match] (mut c Context) http.Response { return route_match.handler.handle(mut c) }) } } // 如果没有匹配的路由,使用 notFound 处理器 param_map := map[string]string{} body := req.data mut ctx := Context.new(req, param_map, query_map, body) // 使用自定义 notFound 处理器或默认 404 响应 if handler := s.app.not_found_handler { return s.exec_context_middlewares(0, mut ctx, handler) } // 默认 404 响应 return s.exec_context_middlewares(0, mut ctx, fn (mut c Context) http.Response { c.status(404) return c.text('Not Found') }) } // 获取路径对应的所有中间件(全局 + 路由前缀匹配的) fn (s ServerHanler) get_middlewares_for_path(path string) []ContextMiddleware { mut middlewares := s.app.context_middlewares.clone() // 按前缀长度排序,确保更具体的前缀后执行 mut prefixes := s.app.route_middlewares.keys() prefixes.sort(a.len < b.len) for prefix in prefixes { if path.starts_with(prefix) || prefix == '/' { if mws := s.app.route_middlewares[prefix] { middlewares << mws } } } return middlewares } // 使用指定中间件列表执行 fn (mut s ServerHanler) exec_context_middlewares_with_list(idx int, middlewares []ContextMiddleware, mut ctx Context, handler fn (mut Context) http.Response) http.Response { if idx < middlewares.len { mw := middlewares[idx] return mw(mut ctx, fn [mut s, idx, middlewares, handler] (mut c Context) http.Response { return s.exec_context_middlewares_with_list(idx + 1, middlewares, mut c, handler) }) } else { return handler(mut ctx) } } // Context 版本的中间件执行函数 fn (mut s ServerHanler) exec_context_middlewares(idx int, mut ctx Context, handler fn (mut Context) http.Response) http.Response { if idx < s.app.context_middlewares.len { mw := s.app.context_middlewares[idx] return mw(mut ctx, fn [mut s, idx, handler] (mut c Context) http.Response { return s.exec_context_middlewares(idx+1, mut c, handler) }) } else { return handler(mut ctx) } } pub fn (mut app Hono) listen(port string) { // 解析端口号 port_num := port.trim(':').int() if port_num <= 0 { eprintln('[v-hono] Invalid port: ${port}') return } // 默认使用 picoev 高性能服务器 app.listen_picoev(port_num) } // 使用传统 http.Server 启动(保留兼容性) pub fn (mut app Hono) listen_http(port string) { app.server.addr = port app.server.handler = server_hanler_new(app) // 增加超时配置以支持更好的 Keep-Alive app.server.read_timeout = 60 * time.second app.server.write_timeout = 60 * time.second app.server.listen_and_serve() } pub fn (mut app Hono) route(prefix string, mut subapp Hono) { // 保存子应用引用 app.routes[prefix] = subapp // 合并子应用的中间件到路由前缀 if subapp.context_middlewares.len > 0 { if prefix in app.route_middlewares { app.route_middlewares[prefix] << subapp.context_middlewares } else { app.route_middlewares[prefix] = subapp.context_middlewares.clone() } } // 继承子应用的 notFound 和 onError 处理器(如果主应用没有设置) if app.not_found_handler == none && subapp.not_found_handler != none { // 子应用的 notFound 只对该前缀生效,这里不继承到主应用 // 如果需要,可以在子应用路由匹配失败时单独处理 } // 合并子应用的路由到主应用的所有路由器 // 使用辅助函数来处理每种 HTTP 方法 app.merge_routes_for_method('GET', prefix, subapp.context_router.handlers.get) app.merge_routes_for_method('POST', prefix, subapp.context_router.handlers.post) app.merge_routes_for_method('PUT', prefix, subapp.context_router.handlers.put) app.merge_routes_for_method('DELETE', prefix, subapp.context_router.handlers.delete) app.merge_routes_for_method('PATCH', prefix, subapp.context_router.handlers.patch) app.merge_routes_for_method('HEAD', prefix, subapp.context_router.handlers.head) app.merge_routes_for_method('OPTIONS', prefix, subapp.context_router.handlers.options) } // 辅助函数:合并指定 HTTP 方法的路由 fn (mut app Hono) merge_routes_for_method(method string, prefix string, handlers []IHandler) { for handler in handlers { // 创建带前缀的新路径 mut new_path := '' if handler.path == '/' || handler.path == '' { // 如果子路由是根路径,直接使用前缀 new_path = prefix } else if handler.path.starts_with('/') { new_path = '${prefix}${handler.path}' } else { new_path = '${prefix}/${handler.path}' } // 创建带新路径的包装 handler(实现 IHandler 接口) new_handler := PrefixedHandler{ path: new_path inner: handler } // 为 trie_router 创建 ContextHandler trie_handler := ContextHandler{ path: new_path handler: fn [handler] (mut c Context) http.Response { return handler.handle(mut c) } } // 添加到对应的 handlers 列表 match method { 'GET' { app.context_router.handlers.get << new_handler } 'POST' { app.context_router.handlers.post << new_handler } 'PUT' { app.context_router.handlers.put << new_handler } 'DELETE' { app.context_router.handlers.delete << new_handler } 'PATCH' { app.context_router.handlers.patch << new_handler } 'HEAD' { app.context_router.handlers.head << new_handler } 'OPTIONS' { app.context_router.handlers.options << new_handler } else {} } // 添加到快速路由器 if app.use_fast_router { app.fast_router.add_route(method, new_handler, '') or { app.context_hybrid_router.add_route(method, new_handler, '') } } else { app.context_hybrid_router.add_route(method, new_handler, '') } app.context_trie_router.add_route(method, new_path, trie_handler) } } // 带前缀的 Handler 包装器,实现 IHandler 接口 pub struct PrefixedHandler { pub: path string inner IHandler } // 实现 IHandler 接口的 handle 方法 pub fn (h PrefixedHandler) handle(mut c Context) http.Response { return h.inner.handle(mut c) } pub fn (mut app Hono) set_base_path(base_path string) { app.base_path = base_path } // 路由统计信息 pub fn (app Hono) get_router_stats() (int, int, int, int) { if app.use_fast_router { static_count, dynamic_count, cache_count := app.fast_router.get_stats() return static_count, dynamic_count, cache_count, 0 } else { static_paths, dynamic_paths := app.context_hybrid_router.get_all_routes() cache_size, cache_capacity := app.context_hybrid_router.get_cache_stats() return static_paths.len, dynamic_paths.len, cache_size, cache_capacity } } // 清理缓存 pub fn (mut app Hono) clear_cache() { if app.use_fast_router { app.fast_router.clear_cache() } else { app.context_hybrid_router.clear_cache() } } // 启用/禁用快速路由器 pub fn (mut app Hono) set_fast_router_enabled(enabled bool) { app.use_fast_router = enabled println('[INFO] FastRouter ${if enabled { 'enabled' } else { 'disabled' }}') } // 获取路由器性能分析 pub fn (mut app Hono) analyze_router_performance() { if app.use_fast_router { app.fast_router.analyze_performance() } else { app.context_hybrid_router.analyze_router_performance() } } pub fn Hono.new() Hono { return Hono{ server: http.Server{} routes: map[string]Hono{} base_path: '' not_found_handler: none error_handler: none context_router: ContextRouter{} context_hybrid_router: ContextHybridRouter.new() context_trie_router: ContextTrieRouter.new() fast_router: FastRouter.new() use_fast_router: true route_middlewares: map[string][]ContextMiddleware{} } }