use awebframework::response::IntoResponse; use awebframework::{async_trait, extract::FromRequest, prelude::*}; use http::Response; use http::StatusCode; use std::net::SocketAddr; #[tokio::main] async fn main() { tracing_subscriber::fmt::init(); // build our application with some routes let app = route("/:version/foo", get(handler)); // run it let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); tracing::debug!("listening on {}", addr); app.serve(&addr).await.unwrap(); } async fn handler(version: Version) { println!("received request with version {:?}", version); } #[derive(Debug)] enum Version { V1, V2, V3, } #[async_trait] impl FromRequest for Version { type Rejection = Response; async fn from_request(req: &mut Request) -> Result { let params = extract::UrlParamsMap::from_request(req) .await .map_err(IntoResponse::into_response)?; let version = params .get("version") .ok_or_else(|| (StatusCode::NOT_FOUND, "version param missing").into_response())?; match version { "v1" => Ok(Version::V1), "v2" => Ok(Version::V2), "v3" => Ok(Version::V3), _ => Err((StatusCode::NOT_FOUND, "unknown version").into_response()), } } }