tako_rs_core/router/introspection.rs
1//! Read-only introspection over a [`Router`]'s registered routes.
2
3use std::sync::Arc;
4use std::sync::Weak;
5
6use super::Router;
7use crate::route::Route;
8
9impl Router {
10 /// Returns every route currently registered on this router.
11 ///
12 /// Routes come back grouped by HTTP method in the standard GET, POST, PUT,
13 /// DELETE, PATCH, HEAD, OPTIONS, CONNECT, TRACE order, and within a method in
14 /// registration order. Each path is the final registered path, so any prefix
15 /// applied by [`Router::scope`] or [`Router::nest`] is already baked in — the
16 /// returned set cannot drift from what the router actually dispatches, which
17 /// is the whole point of asking the router instead of tracking routes
18 /// separately.
19 ///
20 /// This is a cold-path accessor for startup-time inspection — route
21 /// listings, reserved-namespace checks, generated documentation — not for the
22 /// dispatch hot path.
23 ///
24 /// # Examples
25 ///
26 /// ```rust
27 /// use tako::{router::Router, Method, types::Request};
28 ///
29 /// let mut router = Router::new();
30 /// router.route(Method::GET, "/health", |_req: Request| async { "OK" });
31 /// router.route(Method::POST, "/shorten", |_req: Request| async { "OK" });
32 ///
33 /// let paths: Vec<_> = router.routes().iter().map(|r| r.path.clone()).collect();
34 /// assert_eq!(router.routes().len(), 2);
35 /// assert!(paths.contains(&"/health".to_string()));
36 /// ```
37 #[must_use]
38 pub fn routes(&self) -> Vec<Arc<Route>> {
39 self
40 .routes
41 .iter()
42 .flat_map(|(_, weak_vec)| weak_vec.iter())
43 .filter_map(Weak::upgrade)
44 .collect()
45 }
46}