Skip to main content

Router

Struct Router 

Source
pub struct Router { /* private fields */ }
Expand description

The Actus router. Dispatches requests to controllers by longest-prefix match over the route tree at arbitrary depth.

Implementations§

Source§

impl Router

Source

pub fn match_controller(&self, path_parts: &[String]) -> Option<RouteMatch>

Find which controller a path would hit and the leftover-segments action, without invoking the controller. Returns None if no controller matches (→ 404).

The verb-level resolution (which routes! line the action will dispatch to, or 405 if none match the verb) happens inside the controller’s actus_dispatch; this method only does the path-tree walk.

Source

pub async fn route(&self, path_parts: &[String], params: Params) -> Reply

Routes a request to the appropriate controller and action: thin wrapper around Router::match_controller that also invokes actus_dispatch. Kept for callers (mostly tests) that don’t need to inspect the matched controller before dispatch — the server uses the two-step shape so it can buffer the body with the right cap between match and dispatch.

Source

pub fn routes(&self) -> Vec<(String, RouteDef)>

Walk the route tree and return every (mount_path, RouteDef) pair.

mount_path is the slash-joined path segments where the controller was mounted (no leading or trailing slash) — "" for a root mount, "api/users" for app_routes!{ "api/users" => UserController, ... }, etc. Each controller contributes one entry per RouteDef it describes via Controller::actus_describe_routes.

Used by introspection tools (OpenAPI doc generators, route audit scripts). Order matches a DFS over the route tree; within a single controller, routes are emitted in the order Controller::actus_describe_routes returns them (which is the order they were declared in the routes! block).

Source

pub fn rate_limit_classes(&self) -> Vec<RateLimitClass>

Walk the route tree and return (mount_path, class) for every mounted controller that declared a rate-limit class via #[controller(rate_limit = "…")]. Controllers with no class are skipped. mount_path follows the same convention as Router::routes ("" for a root mount); order is a deterministic DFS (children sorted), so diagnostics and tests get stable output.

This exposes the declared half of the rate-limit picture — the half only the router knows. An application’s rate-limit middleware holds the other half (the classes it has a policy for), so main() can diff the two at startup and assert every declared class is covered. That turns a typo’d class ("ath" for "auth") into a boot failure instead of a silently-unlimited controller. One tree walk; no per-request cost.

⚠️ Emptiness asymmetry. This method catches a misspelling and is blind to an omission: a controller that declared no class produces no row here, so nothing can notice its absence. For rate limiting that is usually fine (an unlimited controller is usually intended). When the omission itself is the failure you’re checking for — route-family coverage — use Router::mounts, which emits a row for every mounted controller, declared or not. (This method keeps its historical shape; mounts() is the absence-inclusive inventory.)

Source

pub fn mounts(&self) -> Vec<Mount>

Walk the route tree and return one Mount row per mounted controller — the per-mount inventory: mount path, controller name, declared caller expectation (floor), prepare hook presence, rate-limit class, and body cap.

Absence is a row, not a skip. A controller that declared nothing appears with expects: None, which is what makes a route-family coverage check possible: the check’s job is precisely to catch the controller that silently declared nothing under a prefix whose other controllers all did. (Contrast Router::rate_limit_classes, which emits only declaring controllers.)

Order is a deterministic DFS (children sorted), matching Router::routes; mount follows the same convention ("" for a root mount). One tree walk; no per-request cost. Typical use: a startup coverage check in main(), a route dump, or building a mount → floor map for a declaration-keyed gate — see the README’s “Route families” section.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more