tako_rs_core/route/
def.rs1use std::sync::Arc;
9use std::sync::OnceLock;
10use std::sync::atomic::AtomicBool;
11use std::sync::atomic::Ordering;
12use std::time::Duration;
13
14use arc_swap::ArcSwap;
15use http::Method;
16#[cfg(any(feature = "plugins", feature = "utoipa", feature = "vespera"))]
17use parking_lot::RwLock;
18
19use crate::extractors::json::SimdJsonMode;
20use crate::handler::BoxHandler;
21#[cfg(any(feature = "utoipa", feature = "vespera"))]
22use crate::openapi::RouteOpenApi;
23#[cfg(feature = "plugins")]
24use crate::plugins::TakoPlugin;
25#[cfg(feature = "signals")]
26use crate::signals::SignalArbiter;
27use crate::types::BoxMiddleware;
28
29#[doc(alias = "route")]
31pub struct Route {
32 pub path: String,
34 pub method: Method,
36 pub(crate) handler: BoxHandler,
43 pub(crate) middlewares: ArcSwap<Vec<BoxMiddleware>>,
50 pub(crate) has_middleware: AtomicBool,
52 pub tsr: bool,
54 #[cfg(feature = "plugins")]
56 pub(crate) plugins: RwLock<Vec<Box<dyn TakoPlugin>>>,
57 #[cfg(feature = "plugins")]
59 pub(crate) plugins_initialized: AtomicBool,
60 pub(crate) http_protocol: OnceLock<http::Version>,
62 #[cfg(feature = "signals")]
64 pub(crate) signals: SignalArbiter,
65 #[cfg(any(feature = "utoipa", feature = "vespera"))]
67 pub(crate) openapi: RwLock<Option<RouteOpenApi>>,
68 pub(crate) timeout: OnceLock<Duration>,
70 pub(crate) simd_json_mode: OnceLock<SimdJsonMode>,
72}
73
74impl Route {
75 pub fn new(path: String, method: Method, handler: BoxHandler, tsr: Option<bool>) -> Self {
77 Self {
78 path,
79 method,
80 handler,
81 middlewares: ArcSwap::new(Arc::default()),
82 has_middleware: AtomicBool::new(false),
83 tsr: tsr.unwrap_or(false),
84 #[cfg(feature = "plugins")]
85 plugins: RwLock::new(Vec::new()),
86 #[cfg(feature = "plugins")]
87 plugins_initialized: AtomicBool::new(false),
88 http_protocol: OnceLock::new(),
89 #[cfg(feature = "signals")]
90 signals: SignalArbiter::new(),
91 #[cfg(any(feature = "utoipa", feature = "vespera"))]
92 openapi: RwLock::new(None),
93 timeout: OnceLock::new(),
94 simd_json_mode: OnceLock::new(),
95 }
96 }
97
98 pub(crate) fn cloned_with_path(&self, new_path: String) -> Arc<Route> {
107 let cloned = Self {
108 path: new_path,
109 method: self.method.clone(),
110 handler: self.handler.clone(),
111 middlewares: ArcSwap::new(self.middlewares.load_full()),
112 has_middleware: AtomicBool::new(self.has_middleware.load(Ordering::Acquire)),
113 tsr: self.tsr,
114 #[cfg(feature = "plugins")]
115 plugins: RwLock::new(Vec::new()),
116 #[cfg(feature = "plugins")]
117 plugins_initialized: AtomicBool::new(true),
118 http_protocol: {
119 let lock = OnceLock::new();
120 if let Some(v) = self.http_protocol.get() {
121 let _ = lock.set(*v);
122 }
123 lock
124 },
125 #[cfg(feature = "signals")]
129 signals: self.signals.clone(),
130 #[cfg(any(feature = "utoipa", feature = "vespera"))]
131 openapi: RwLock::new(self.openapi.read().clone()),
132 timeout: {
133 let lock = OnceLock::new();
134 if let Some(v) = self.timeout.get() {
135 let _ = lock.set(*v);
136 }
137 lock
138 },
139 simd_json_mode: {
140 let lock = OnceLock::new();
141 if let Some(v) = self.simd_json_mode.get() {
142 let _ = lock.set(*v);
143 }
144 lock
145 },
146 };
147 Arc::new(cloned)
148 }
149}