diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ae1b55dc1..66eb21978f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,13 +28,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `routing::EmptyRouterFuture` moved to `routing::future::EmptyRouterFuture` ([#133](/~https://github.com/tokio-rs/axum/pull/133)) - `routing::RouteFuture` moved to `routing::future::RouteFuture` ([#133](/~https://github.com/tokio-rs/axum/pull/133)) - `service::BoxResponseBodyFuture` moved to `service::future::BoxResponseBodyFuture` ([#133](/~https://github.com/tokio-rs/axum/pull/133)) -- The following types no longer implement `Copy` ([#132](/~https://github.com/tokio-rs/axum/pull/132)): +- The following types no longer implement `Copy` ([#132](/~https://github.com/tokio-rs/axum/pull/132)) - `EmptyRouter` - `ExtractorMiddleware` - `ExtractorMiddlewareLayer` - Replace `axum::body::BoxStdError` with `axum::Error`, which supports downcasting ([#150](/~https://github.com/tokio-rs/axum/pull/150)) - `WebSocket` now uses `axum::Error` as its error type ([#150](/~https://github.com/tokio-rs/axum/pull/150)) -- `RequestParts` changes: +- `RequestParts` changes ([#153](/~https://github.com/tokio-rs/axum/pull/153)) - `method` new returns an `&http::Method` - `method_mut` new returns an `&mut http::Method` - `take_method` has been removed @@ -42,9 +42,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `uri_mut` new returns an `&mut http::Uri` - `take_uri` has been removed - These rejections have been removed as they're no longer used - - `MethodAlreadyExtracted` - - `UriAlreadyExtracted` - - `VersionAlreadyExtracted` + - `MethodAlreadyExtracted` ([#153](/~https://github.com/tokio-rs/axum/pull/153)) + - `UriAlreadyExtracted` ([#153](/~https://github.com/tokio-rs/axum/pull/153)) + - `VersionAlreadyExtracted` ([#153](/~https://github.com/tokio-rs/axum/pull/153)) + - `UrlParamsRejection` + - `InvalidUrlParam` +- Removed `extract::UrlParams` and `extract::UrlParamsMap`. Use `extract::Path` instead # 0.1.3 (06. August, 2021) diff --git a/src/extract/mod.rs b/src/extract/mod.rs index 1ba4015d56..da37e282c5 100644 --- a/src/extract/mod.rs +++ b/src/extract/mod.rs @@ -79,7 +79,7 @@ //! //! async fn handler( //! // Extract captured parameters from the URL -//! params: extract::UrlParamsMap, +//! params: extract::Path>, //! // Parse query string into a `HashMap` //! query_params: extract::Query>, //! // Buffer the request body into a `Bytes` @@ -266,8 +266,6 @@ mod query; mod raw_query; mod request_parts; mod tuple; -mod url_params; -mod url_params_map; #[doc(inline)] #[allow(deprecated)] @@ -281,8 +279,6 @@ pub use self::{ query::Query, raw_query::RawQuery, request_parts::{Body, BodyStream}, - url_params::UrlParams, - url_params_map::UrlParamsMap, }; #[doc(no_inline)] pub use crate::Json; diff --git a/src/extract/rejection.rs b/src/extract/rejection.rs index a2382db19b..7bde742138 100644 --- a/src/extract/rejection.rs +++ b/src/extract/rejection.rs @@ -82,9 +82,7 @@ define_rejection! { define_rejection! { #[status = INTERNAL_SERVER_ERROR] #[body = "No url params found for matched route. This is a bug in axum. Please open an issue"] - /// Rejection type for [`UrlParamsMap`](super::UrlParamsMap) and - /// [`UrlParams`](super::UrlParams) if you try and extract the URL params - /// more than once. + /// Rejection type used if you try and extract the URL params more than once. pub struct MissingRouteParams; } @@ -110,44 +108,6 @@ define_rejection! { pub struct InvalidFormContentType; } -/// Rejection type for [`UrlParams`](super::UrlParams) if the capture route -/// param didn't have the expected type. -#[derive(Debug)] -pub struct InvalidUrlParam { - type_name: &'static str, -} - -impl InvalidUrlParam { - pub(super) fn new() -> Self { - InvalidUrlParam { - type_name: std::any::type_name::(), - } - } -} - -impl std::fmt::Display for InvalidUrlParam { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "Invalid URL param. Expected something of type `{}`", - self.type_name - ) - } -} - -impl std::error::Error for InvalidUrlParam {} - -impl IntoResponse for InvalidUrlParam { - type Body = Full; - type BodyError = Infallible; - - fn into_response(self) -> http::Response { - let mut res = http::Response::new(Full::from(self.to_string())); - *res.status_mut() = http::StatusCode::BAD_REQUEST; - res - } -} - /// Rejection type for [`Path`](super::Path) if the capture route /// param didn't have the expected type. #[derive(Debug)] @@ -269,17 +229,6 @@ composite_rejection! { } } -composite_rejection! { - /// Rejection used for [`UrlParams`](super::UrlParams). - /// - /// Contains one variant for each way the [`UrlParams`](super::UrlParams) extractor - /// can fail. - pub enum UrlParamsRejection { - InvalidUrlParam, - MissingRouteParams, - } -} - composite_rejection! { /// Rejection used for [`Path`](super::Path). /// diff --git a/src/extract/url_params.rs b/src/extract/url_params.rs deleted file mode 100644 index 84b97db53c..0000000000 --- a/src/extract/url_params.rs +++ /dev/null @@ -1,100 +0,0 @@ -use super::{rejection::*, FromRequest, RequestParts}; -use async_trait::async_trait; -use std::{ops::Deref, str::FromStr}; - -/// Extractor that will get captures from the URL and parse them. -/// -/// # Example -/// -/// ```rust,no_run -/// use axum::{extract::UrlParams, prelude::*}; -/// use uuid::Uuid; -/// -/// async fn users_teams_show( -/// UrlParams(params): UrlParams<(Uuid, Uuid)>, -/// ) { -/// let user_id: Uuid = params.0; -/// let team_id: Uuid = params.1; -/// -/// // ... -/// } -/// -/// let app = route("/users/:user_id/team/:team_id", get(users_teams_show)); -/// # async { -/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap(); -/// # }; -/// ``` -/// -/// Note that you can only have one URL params extractor per handler. If you -/// have multiple it'll response with `500 Internal Server Error`. -#[derive(Debug)] -#[deprecated(since = "0.1.3", note = "Use `axum::extract::Path` instead.")] -pub struct UrlParams(pub T); - -macro_rules! impl_parse_url { - () => {}; - - ( $head:ident, $($tail:ident),* $(,)? ) => { - #[async_trait] - #[allow(deprecated)] - impl FromRequest for UrlParams<($head, $($tail,)*)> - where - $head: FromStr + Send, - $( $tail: FromStr + Send, )* - B: Send, - { - type Rejection = UrlParamsRejection; - - #[allow(non_snake_case)] - async fn from_request(req: &mut RequestParts) -> Result { - let params = if let Some(params) = req - .extensions_mut() - .and_then(|ext| { - ext.get_mut::>() - }) - { - if let Some(params) = params { - params.0.clone() - } else { - Default::default() - } - } else { - return Err(MissingRouteParams.into()) - }; - - if let [(_, $head), $((_, $tail),)*] = &*params { - let $head = if let Ok(x) = $head.as_str().parse::<$head>() { - x - } else { - return Err(InvalidUrlParam::new::<$head>().into()); - }; - - $( - let $tail = if let Ok(x) = $tail.as_str().parse::<$tail>() { - x - } else { - return Err(InvalidUrlParam::new::<$tail>().into()); - }; - )* - - Ok(UrlParams(($head, $($tail,)*))) - } else { - Err(MissingRouteParams.into()) - } - } - } - - impl_parse_url!($($tail,)*); - }; -} - -impl_parse_url!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16); - -#[allow(deprecated)] -impl Deref for UrlParams { - type Target = T; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} diff --git a/src/extract/url_params_map.rs b/src/extract/url_params_map.rs deleted file mode 100644 index f05e5fe766..0000000000 --- a/src/extract/url_params_map.rs +++ /dev/null @@ -1,69 +0,0 @@ -use super::{rejection::*, FromRequest, RequestParts}; -use crate::util::ByteStr; -use async_trait::async_trait; -use std::{collections::HashMap, str::FromStr}; - -/// Extractor that will get captures from the URL. -/// -/// # Example -/// -/// ```rust,no_run -/// use axum::prelude::*; -/// -/// async fn users_show(params: extract::UrlParamsMap) { -/// let id: Option<&str> = params.get("id"); -/// -/// // ... -/// } -/// -/// let app = route("/users/:id", get(users_show)); -/// # async { -/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap(); -/// # }; -/// ``` -/// -/// Note that you can only have one URL params extractor per handler. If you -/// have multiple it'll response with `500 Internal Server Error`. -#[derive(Debug)] -#[deprecated(since = "0.1.3", note = "Use `axum::extract::Path` instead.")] -pub struct UrlParamsMap(HashMap); - -#[allow(deprecated)] -impl UrlParamsMap { - /// Look up the value for a key. - pub fn get(&self, key: &str) -> Option<&str> { - self.0.get(&ByteStr::new(key)).map(|s| s.as_str()) - } - - /// Look up the value for a key and parse it into a value of type `T`. - pub fn get_typed(&self, key: &str) -> Option> - where - T: FromStr, - { - self.get(key).map(str::parse) - } -} - -#[async_trait] -#[allow(deprecated)] -impl FromRequest for UrlParamsMap -where - B: Send, -{ - type Rejection = MissingRouteParams; - - async fn from_request(req: &mut RequestParts) -> Result { - if let Some(params) = req - .extensions_mut() - .and_then(|ext| ext.get_mut::>()) - { - if let Some(params) = params { - Ok(Self(params.0.iter().cloned().collect())) - } else { - Ok(Self(Default::default())) - } - } else { - Err(MissingRouteParams) - } - } -} diff --git a/src/routing.rs b/src/routing.rs index 38d16fedf2..71931c5184 100644 --- a/src/routing.rs +++ b/src/routing.rs @@ -830,8 +830,9 @@ where /// /// ``` /// use axum::{routing::nest, prelude::*}; +/// use std::collections::HashMap; /// -/// async fn users_get(params: extract::UrlParamsMap) { +/// async fn users_get(extract::Path(params): extract::Path>) { /// // Both `version` and `id` were captured even though `users_api` only /// // explicitly captures `id`. /// let version = params.get("version");