use std::sync::Arc;
use std::sync::Weak;
use std::sync::atomic::AtomicBool;
use std::time::Duration;
use arc_swap::ArcSwap;
use super::ErrorHandler;
use super::method_map::MethodMap;
use crate::handler::BoxHandler;
#[cfg(feature = "plugins")]
use crate::plugins::TakoPlugin;
use crate::route::Route;
use crate::router_state::RouterState;
#[cfg(feature = "signals")]
use crate::signals::SignalArbiter;
use crate::types::BoxMiddleware;
#[doc(alias = "router")]
pub struct Router {
pub(crate) inner: MethodMap<matchit::Router<Arc<Route>>>,
pub(crate) routes: MethodMap<Vec<Weak<Route>>>,
pub(crate) pending_prefix: Option<String>,
pub(crate) middlewares: ArcSwap<Vec<BoxMiddleware>>,
pub(crate) has_global_middleware: AtomicBool,
pub(crate) fallback: Option<BoxHandler>,
#[cfg(feature = "plugins")]
pub(crate) plugins: Vec<Box<dyn TakoPlugin>>,
#[cfg(feature = "plugins")]
pub(crate) plugins_initialized: AtomicBool,
#[cfg(feature = "signals")]
pub(crate) signals: SignalArbiter,
pub(crate) timeout: Option<Duration>,
pub(crate) timeout_fallback: Option<BoxHandler>,
pub(crate) error_handler: Option<ErrorHandler>,
pub(crate) client_error_handler: Option<ErrorHandler>,
pub(crate) router_state: Arc<RouterState>,
pub(crate) has_router_state: AtomicBool,
}
impl Default for Router {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl Router {
#[must_use]
pub fn new() -> Self {
let router = Self {
inner: MethodMap::new(),
routes: MethodMap::new(),
pending_prefix: None,
middlewares: ArcSwap::new(Arc::default()),
has_global_middleware: AtomicBool::new(false),
fallback: None,
#[cfg(feature = "plugins")]
plugins: Vec::new(),
#[cfg(feature = "plugins")]
plugins_initialized: AtomicBool::new(false),
#[cfg(feature = "signals")]
signals: SignalArbiter::new(),
timeout: None,
timeout_fallback: None,
error_handler: None,
client_error_handler: None,
router_state: Arc::new(RouterState::new()),
has_router_state: AtomicBool::new(false),
};
#[cfg(feature = "signals")]
{
let arbiter_clone = router.signals.clone();
let _ = crate::state::get_or_init_state::<SignalArbiter, _>(move || arbiter_clone);
}
router
}
}