From 460828a3cb2b2d7e8bea3c79d396b82cf85035d4 Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Sun, 13 Jun 2021 13:50:56 +0200 Subject: [PATCH] Add versioning extractor example (#16) --- examples/versioning.rs | 51 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 examples/versioning.rs diff --git a/examples/versioning.rs b/examples/versioning.rs new file mode 100644 index 00000000..a80b714c --- /dev/null +++ b/examples/versioning.rs @@ -0,0 +1,51 @@ +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()), + } + } +}