1
0
mirror of https://github.com/actix/actix-extras.git synced 2025-06-26 02:19:22 +02:00

remove Path and Query from public api

This commit is contained in:
Nikolay Kim
2018-03-26 18:18:38 -07:00
parent 052d5f0bc5
commit 8fff2c7595
6 changed files with 84 additions and 28 deletions

View File

@ -13,6 +13,7 @@ use http2::Error as Http2Error;
use http::{header, StatusCode, Error as HttpError};
use http::uri::InvalidUri;
use http_range::HttpRangeParseError;
use serde::de::value::Error as DeError;
use serde_json::error::Error as JsonError;
pub use url::ParseError as UrlParseError;
@ -109,6 +110,13 @@ impl ResponseError for JsonError {}
/// `InternalServerError` for `UrlParseError`
impl ResponseError for UrlParseError {}
/// Return `BAD_REQUEST` for `de::value::Error`
impl ResponseError for DeError {
fn error_response(&self) -> HttpResponse {
HttpResponse::new(StatusCode::BAD_REQUEST, Body::Empty)
}
}
/// Return `InternalServerError` for `HttpError`,
/// Response generation can return `HttpError`, so it is internal error
impl ResponseError for HttpError {}

View File

@ -1,11 +1,10 @@
use serde_urlencoded;
use serde::de::{self, Deserializer, Visitor, Error as DeError};
use error::{Error, ErrorBadRequest};
use httprequest::HttpRequest;
pub trait HttpRequestExtractor<'de> {
fn extract<T, S>(&self, req: &'de HttpRequest<S>) -> Result<T, Error>
fn extract<T, S>(&self, req: &'de HttpRequest<S>) -> Result<T, de::value::Error>
where T: de::Deserialize<'de>, S: 'static;
}
@ -19,6 +18,7 @@ pub trait HttpRequestExtractor<'de> {
/// # extern crate futures;
/// #[macro_use] extern crate serde_derive;
/// use actix_web::*;
/// use actix_web::dev::{Path, HttpRequestExtractor};
///
/// #[derive(Deserialize)]
/// struct Info {
@ -26,7 +26,7 @@ pub trait HttpRequestExtractor<'de> {
/// }
///
/// fn index(mut req: HttpRequest) -> Result<String> {
/// let info: Info = req.extract(Path)?; // <- extract path info using serde
/// let info: Info = Path.extract(&req)?; // <- extract path info using serde
/// Ok(format!("Welcome {}!", info.username))
/// }
///
@ -40,11 +40,10 @@ pub struct Path;
impl<'de> HttpRequestExtractor<'de> for Path {
#[inline]
fn extract<T, S>(&self, req: &'de HttpRequest<S>) -> Result<T, Error>
fn extract<T, S>(&self, req: &'de HttpRequest<S>) -> Result<T, de::value::Error>
where T: de::Deserialize<'de>, S: 'static,
{
Ok(de::Deserialize::deserialize(PathExtractor{req: req})
.map_err(ErrorBadRequest)?)
de::Deserialize::deserialize(PathExtractor{req: req})
}
}
@ -58,6 +57,7 @@ impl<'de> HttpRequestExtractor<'de> for Path {
/// # extern crate futures;
/// #[macro_use] extern crate serde_derive;
/// use actix_web::*;
/// use actix_web::dev::{Query, HttpRequestExtractor};
///
/// #[derive(Deserialize)]
/// struct Info {
@ -65,7 +65,7 @@ impl<'de> HttpRequestExtractor<'de> for Path {
/// }
///
/// fn index(mut req: HttpRequest) -> Result<String> {
/// let info: Info = req.extract(Query)?; // <- extract query info using serde
/// let info: Info = Query.extract(&req)?; // <- extract query info using serde
/// Ok(format!("Welcome {}!", info.username))
/// }
///
@ -75,11 +75,10 @@ pub struct Query;
impl<'de> HttpRequestExtractor<'de> for Query {
#[inline]
fn extract<T, S>(&self, req: &'de HttpRequest<S>) -> Result<T, Error>
fn extract<T, S>(&self, req: &'de HttpRequest<S>) -> Result<T, de::value::Error>
where T: de::Deserialize<'de>, S: 'static,
{
Ok(serde_urlencoded::from_str::<T>(req.query_string())
.map_err(ErrorBadRequest)?)
serde_urlencoded::from_str::<T>(req.query_string())
}
}
@ -189,7 +188,6 @@ impl<'de, S: 'static> Deserializer<'de> for PathExtractor<'de, S>
#[cfg(test)]
mod tests {
use super::*;
use router::{Router, Pattern};
use resource::Resource;
use test::TestRequest;
@ -217,15 +215,15 @@ mod tests {
let (router, _) = Router::new("", ServerSettings::default(), routes);
assert!(router.recognize(&mut req).is_some());
let s: MyStruct = req.extract(Path).unwrap();
let s: MyStruct = req.extract_path().unwrap();
assert_eq!(s.key, "name");
assert_eq!(s.value, "user1");
let s: (String, String) = req.extract(Path).unwrap();
let s: (String, String) = req.extract_path().unwrap();
assert_eq!(s.0, "name");
assert_eq!(s.1, "user1");
let s: Id = req.extract(Query).unwrap();
let s: Id = req.extract_query().unwrap();
assert_eq!(s.id, "test");
}
}

View File

@ -20,7 +20,7 @@ use payload::Payload;
use httpmessage::HttpMessage;
use httpresponse::{HttpResponse, HttpResponseBuilder};
use helpers::SharedHttpInnerMessage;
use extractor::HttpRequestExtractor;
use extractor::{Path, Query, HttpRequestExtractor};
use error::{Error, UrlGenerationError, CookieParseError, PayloadError};
@ -383,6 +383,7 @@ impl<S> HttpRequest<S> {
}
/// Get a reference to the Params object.
///
/// Params is a container for url parameters.
/// Route supports glob patterns: * for a single wildcard segment and :param
/// for matching storing that segment of the request url in the Params object.
@ -397,14 +398,15 @@ impl<S> HttpRequest<S> {
unsafe{ mem::transmute(&mut self.as_mut().params) }
}
/// Extract typed information from path.
/// Extract typed information from request's path.
///
/// By default, in case of error `BAD_REQUEST` response get returned to peer.
/// If you need to return different response use `map_err()` method.
///
/// ## Example
///
/// ```rust
/// # extern crate bytes;
/// # extern crate actix_web;
/// # extern crate futures;
/// #[macro_use] extern crate serde_derive;
/// use actix_web::*;
///
@ -414,8 +416,7 @@ impl<S> HttpRequest<S> {
/// }
///
/// fn index(mut req: HttpRequest) -> Result<String> {
/// let info: Info = req.extract(Path)?; // <- extract path info using serde
/// let info: Info = req.extract(Query)?; // <- extract query info
/// let info: Info = req.extract_path()?; // <- extract path info using serde
/// Ok(format!("Welcome {}!", info.username))
/// }
///
@ -425,12 +426,60 @@ impl<S> HttpRequest<S> {
/// |r| r.method(Method::GET).f(index));
/// }
/// ```
pub fn extract<'a, T, D>(&'a self, ds: D) -> Result<T, Error>
pub fn extract_path<'a, T>(&'a self) -> Result<T, Error>
where S: 'static,
T: de::Deserialize<'a>,
D: HttpRequestExtractor<'a>
{
ds.extract(self)
Ok(Path.extract(self)?)
}
/// Extract typed information from request's query string.
///
/// ## Example
///
/// ```rust
/// # extern crate actix_web;
/// #[macro_use] extern crate serde_derive;
/// use actix_web::{HttpRequest, Result};
///
/// #[derive(Deserialize)]
/// struct Info {
/// username: String,
/// }
///
/// fn index(mut req: HttpRequest) -> Result<String> {
/// let info: Info = req.extract_query()?; // <- extract query info, i.e: /?id=username
/// Ok(format!("Welcome {}!", info.username))
/// }
/// # fn main() {}
/// ```
///
/// By default, in case of error, `BAD_REQUEST` response get returned to peer.
/// If you need to return different response use `map_err()` method.
///
/// ```rust
/// # extern crate actix_web;
/// #[macro_use] extern crate serde_derive;
/// use actix_web::{HttpRequest, Result, error};
///
/// #[derive(Deserialize)]
/// struct Info {
/// username: String,
/// }
///
/// fn index(mut req: HttpRequest) -> Result<String> {
/// let info: Info = req.extract_query() // <- extract query information
/// .map_err(error::ErrorInternalServerError)?; // <- return 500 in case of error
/// Ok(format!("Welcome {}!", info.username))
/// }
/// # fn main() {}
/// ```
///
pub fn extract_query<'a, T>(&'a self) -> Result<T, Error>
where S: 'static,
T: de::Deserialize<'a>,
{
Ok(Query.extract(self)?)
}
/// Checks if a connection should be kept alive.

View File

@ -144,7 +144,6 @@ pub use route::Route;
pub use resource::Resource;
pub use context::HttpContext;
pub use server::HttpServer;
pub use extractor::{Path, Query};
// re-exports
pub use http::{Method, StatusCode, Version};
@ -190,5 +189,5 @@ pub mod dev {
pub use param::{FromParam, Params};
pub use httpmessage::{UrlEncoded, MessageBody};
pub use httpresponse::HttpResponseBuilder;
pub use extractor::HttpRequestExtractor;
pub use extractor::{Path, Query, HttpRequestExtractor};
}