Skip to content

Route Tracing #1878

@cataggar

Description

@cataggar

I want to be be able to test that routes resolve correctly, given the HTTP method and URI.

#[cfg(test)]
mod test {
    use super::*;
    use rocket::Router;

    #[test]
    fn test_route_name() -> Result<(), Error> {
        let mut router = Router::new();
        for route in api_routes() {
            router.add_route(route);
        }

        assert_eq!("Hello".to_owned(), route_name(&router, "GET", "/")?);
        // a lot more asserts
        Ok(())
    }
}

// Get the route name from the HTTP method + URI combination.
fn route_name(router: &Router, method: &str, uri: &str) -> Result<String, Error> {
    let client = rocket::local::blocking::Client::debug_with(Vec::new()).map_err(Error::CreateLocalClient)?;
    let request_method = Method::from_str(method).map_err(|_| Error::InvalidHttpMethod(method.to_owned()))?;
    let request_uri = rocket::http::uri::Origin::parse(uri).map_err(|_| Error::ParseUri(uri.to_owned()))?;
    let request = client.req(request_method, request_uri);
    let mut routes = router.route(&request);
    let route = routes.next().ok_or_else(|| Error::RouteNotFound {
        method: method.to_owned(),
        uri: uri.to_owned(),
    })?;
    let name = route.name.as_ref().ok_or_else(|| Error::UnnamedRoute {
        method: method.to_owned(),
        uri: uri.to_owned(),
    })?;
    Ok(name.to_owned().to_string())
}

#[non_exhaustive]
#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error("unable to create rocket client: {0}")]
    CreateLocalClient(rocket::Error),
    #[error("unable to parse uri: {0}")]
    ParseUri(String),
    #[error("invalid http method: {0}")]
    InvalidHttpMethod(String),
    #[error("route not found for {method} {uri}")]
    RouteNotFound { method: String, uri: String },
    #[error("unnamed route for {method} {uri}")]
    UnnamedRoute { method: String, uri: String },
}

Existing Functionality

Router

Suggested Changes

The above code works if Router is made public #1873 and the route name is settable #1872.

Alternatives Considered

Additional Context

Metadata

Metadata

Assignees

No one assigned

    Labels

    requestRequest for new functionality

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions