diff --git a/examples/key_value_store.rs b/examples/key_value_store.rs
index 8447cee5..324b3de4 100644
--- a/examples/key_value_store.rs
+++ b/examples/key_value_store.rs
@@ -52,7 +52,7 @@ struct State {
async fn get(
_req: Request
,
- params: extract::UrlParams,
+ params: extract::UrlParamsMap,
state: extract::Extension,
) -> Result {
let state = state.into_inner();
@@ -69,7 +69,7 @@ async fn get(
async fn set(
_req: Request,
- params: extract::UrlParams,
+ params: extract::UrlParamsMap,
value: extract::BytesMaxLength<{ 1024 * 5_000 }>, // ~5mb
state: extract::Extension,
) -> Result {
diff --git a/src/error.rs b/src/error.rs
index fcfae63c..dcfa50bc 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -39,6 +39,9 @@ pub enum Error {
#[error("response failed with status {0}")]
Status(StatusCode),
+ #[error("invalid URL param. Expected something of type `{type_name}`")]
+ InvalidUrlParam { type_name: &'static str },
+
#[error("unknown URL param `{0}`")]
UnknownUrlParam(String),
}
@@ -65,7 +68,8 @@ where
match error {
Error::DeserializeRequestBody(_)
| Error::QueryStringMissing
- | Error::DeserializeQueryString(_) => make_response(StatusCode::BAD_REQUEST),
+ | Error::DeserializeQueryString(_)
+ | Error::InvalidUrlParam { .. } => make_response(StatusCode::BAD_REQUEST),
Error::Status(status) => make_response(status),
diff --git a/src/extract.rs b/src/extract.rs
index 998bc232..d1c6b41c 100644
--- a/src/extract.rs
+++ b/src/extract.rs
@@ -184,9 +184,9 @@ impl FromRequest for BytesMaxLength {
}
}
-pub struct UrlParams(HashMap);
+pub struct UrlParamsMap(HashMap);
-impl UrlParams {
+impl UrlParamsMap {
pub fn get(&self, key: &str) -> Result<&str, Error> {
if let Some(value) = self.0.get(key) {
Ok(value)
@@ -194,9 +194,18 @@ impl UrlParams {
Err(Error::UnknownUrlParam(key.to_string()))
}
}
+
+ pub fn get_typed(&self, key: &str) -> Result
+ where
+ T: std::str::FromStr,
+ {
+ self.get(key)?.parse().map_err(|_| Error::InvalidUrlParam {
+ type_name: std::any::type_name::(),
+ })
+ }
}
-impl FromRequest for UrlParams {
+impl FromRequest for UrlParamsMap {
type Future = future::Ready>;
fn from_request(req: &mut Request) -> Self::Future {