Remove UrlParamsMap and UrlParams (#154)

Use `extract::Path` instead.
This commit is contained in:
David Pedersen
2021-08-07 21:22:08 +02:00
committed by GitHub
parent 6a82dd75ea
commit a6b3e09827
6 changed files with 12 additions and 232 deletions
+1 -5
View File
@@ -79,7 +79,7 @@
//!
//! async fn handler(
//! // Extract captured parameters from the URL
//! params: extract::UrlParamsMap,
//! params: extract::Path<HashMap<String, String>>,
//! // Parse query string into a `HashMap`
//! query_params: extract::Query<HashMap<String, String>>,
//! // 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;
+1 -52
View File
@@ -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<T>() -> Self {
InvalidUrlParam {
type_name: std::any::type_name::<T>(),
}
}
}
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<Bytes>;
type BodyError = Infallible;
fn into_response(self) -> http::Response<Self::Body> {
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).
///
-100
View File
@@ -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<T>(pub T);
macro_rules! impl_parse_url {
() => {};
( $head:ident, $($tail:ident),* $(,)? ) => {
#[async_trait]
#[allow(deprecated)]
impl<B, $head, $($tail,)*> FromRequest<B> 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<B>) -> Result<Self, Self::Rejection> {
let params = if let Some(params) = req
.extensions_mut()
.and_then(|ext| {
ext.get_mut::<Option<crate::routing::UrlParams>>()
})
{
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<T> Deref for UrlParams<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
-69
View File
@@ -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<ByteStr, ByteStr>);
#[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<T>(&self, key: &str) -> Option<Result<T, T::Err>>
where
T: FromStr,
{
self.get(key).map(str::parse)
}
}
#[async_trait]
#[allow(deprecated)]
impl<B> FromRequest<B> for UrlParamsMap
where
B: Send,
{
type Rejection = MissingRouteParams;
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
if let Some(params) = req
.extensions_mut()
.and_then(|ext| ext.get_mut::<Option<crate::routing::UrlParams>>())
{
if let Some(params) = params {
Ok(Self(params.0.iter().cloned().collect()))
} else {
Ok(Self(Default::default()))
}
} else {
Err(MissingRouteParams)
}
}
}