mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-24 16:02:59 +01:00
add PathAndQuery extractor
This commit is contained in:
parent
36161aba99
commit
df7ffe14f2
108
src/extractor.rs
108
src/extractor.rs
@ -26,7 +26,7 @@ pub trait HttpRequestExtractor<T, S>: Sized where T: DeserializeOwned, S: 'stati
|
|||||||
/// # extern crate actix_web;
|
/// # extern crate actix_web;
|
||||||
/// # extern crate futures;
|
/// # extern crate futures;
|
||||||
/// #[macro_use] extern crate serde_derive;
|
/// #[macro_use] extern crate serde_derive;
|
||||||
/// use actix_web::*;
|
/// # use actix_web::*;
|
||||||
/// use actix_web::Path;
|
/// use actix_web::Path;
|
||||||
///
|
///
|
||||||
/// /// Application state
|
/// /// Application state
|
||||||
@ -113,7 +113,7 @@ impl<T, S> HttpRequestExtractor<T, S> for Path<T, S>
|
|||||||
/// # extern crate actix_web;
|
/// # extern crate actix_web;
|
||||||
/// # extern crate futures;
|
/// # extern crate futures;
|
||||||
/// #[macro_use] extern crate serde_derive;
|
/// #[macro_use] extern crate serde_derive;
|
||||||
/// use actix_web::*;
|
/// # use actix_web::*;
|
||||||
/// use actix_web::Query;
|
/// use actix_web::Query;
|
||||||
///
|
///
|
||||||
/// /// Application state
|
/// /// Application state
|
||||||
@ -189,6 +189,110 @@ impl<T, S> HttpRequestExtractor<T, S> for Query<T, S>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extract typed information from from the request's path and query.
|
||||||
|
///
|
||||||
|
/// `S` - application state type
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # extern crate bytes;
|
||||||
|
/// # extern crate actix_web;
|
||||||
|
/// # extern crate futures;
|
||||||
|
/// #[macro_use] extern crate serde_derive;
|
||||||
|
/// # use actix_web::*;
|
||||||
|
/// use actix_web::PathAndQuery;
|
||||||
|
///
|
||||||
|
/// /// Application state
|
||||||
|
/// struct State {}
|
||||||
|
///
|
||||||
|
/// #[derive(Deserialize)]
|
||||||
|
/// struct PathParam {
|
||||||
|
/// username: String,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// #[derive(Deserialize)]
|
||||||
|
/// struct QueryParam {
|
||||||
|
/// count: u32,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// // use `with` extractor for query info
|
||||||
|
/// // this handler get called only if request's path contains `username` field
|
||||||
|
/// // and query contains `count` field
|
||||||
|
/// fn index(data: PathAndQuery<PathParam, QueryParam, State>) -> Result<String> {
|
||||||
|
/// Ok(format!("Welcome {}!", data.path().username))
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn main() {
|
||||||
|
/// let app = Application::with_state(State{}).resource(
|
||||||
|
/// "/index.html",
|
||||||
|
/// |r| r.method(Method::GET).with(index)); // <- use `with` extractor
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub struct PathAndQuery<P, Q, S=()>{
|
||||||
|
pitem: P,
|
||||||
|
qitem: Q,
|
||||||
|
req: HttpRequest<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P, Q, S> PathAndQuery<P, Q, S> {
|
||||||
|
|
||||||
|
/// Path information
|
||||||
|
#[inline]
|
||||||
|
pub fn path(&self) -> &P {
|
||||||
|
&self.pitem
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Query information
|
||||||
|
#[inline]
|
||||||
|
pub fn query(&self) -> &Q {
|
||||||
|
&self.qitem
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Shared application state
|
||||||
|
#[inline]
|
||||||
|
pub fn state(&self) -> &S {
|
||||||
|
self.req.state()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Incoming request
|
||||||
|
#[inline]
|
||||||
|
pub fn request(&self) -> &HttpRequest<S> {
|
||||||
|
&self.req
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deconstruct instance into a parts
|
||||||
|
pub fn into(self) -> (P, Q, HttpRequest<S>) {
|
||||||
|
(self.pitem, self.qitem, self.req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, Q, S> HttpRequestExtractor<T, S> for PathAndQuery<T, Q, S>
|
||||||
|
where T: de::DeserializeOwned, Q: de::DeserializeOwned, S: 'static
|
||||||
|
{
|
||||||
|
type Result = FutureResult<Self, Error>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn extract(req: &HttpRequest<S>) -> Self::Result {
|
||||||
|
let req = req.clone();
|
||||||
|
|
||||||
|
let qitem = match serde_urlencoded::from_str::<Q>(req.query_string())
|
||||||
|
.map_err(|e| e.into())
|
||||||
|
{
|
||||||
|
Ok(item) => item,
|
||||||
|
Err(err) => return result(Err(err))
|
||||||
|
};
|
||||||
|
let pitem = match de::Deserialize::deserialize(PathExtractor{req: &req})
|
||||||
|
.map_err(|e| e.into())
|
||||||
|
{
|
||||||
|
Ok(item) => item,
|
||||||
|
Err(err) => return result(Err(err))
|
||||||
|
};
|
||||||
|
|
||||||
|
result(Ok(PathAndQuery{pitem, qitem, req}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! unsupported_type {
|
macro_rules! unsupported_type {
|
||||||
($trait_fn:ident, $name:expr) => {
|
($trait_fn:ident, $name:expr) => {
|
||||||
fn $trait_fn<V>(self, _: V) -> Result<V::Value, Self::Error>
|
fn $trait_fn<V>(self, _: V) -> Result<V::Value, Self::Error>
|
||||||
|
@ -145,7 +145,7 @@ pub use route::Route;
|
|||||||
pub use resource::Resource;
|
pub use resource::Resource;
|
||||||
pub use context::HttpContext;
|
pub use context::HttpContext;
|
||||||
pub use server::HttpServer;
|
pub use server::HttpServer;
|
||||||
pub use extractor::{Path, Query};
|
pub use extractor::{Path, PathAndQuery, Query};
|
||||||
|
|
||||||
// re-exports
|
// re-exports
|
||||||
pub use http::{Method, StatusCode, Version};
|
pub use http::{Method, StatusCode, Version};
|
||||||
|
Loading…
Reference in New Issue
Block a user