2016-08-08 10:10:23 +00:00
|
|
|
use std::fmt::Debug;
|
2016-10-04 00:09:13 +00:00
|
|
|
|
2016-10-25 11:03:50 +00:00
|
|
|
use outcome::{self, IntoOutcome};
|
2016-10-04 00:09:13 +00:00
|
|
|
use request::Request;
|
2016-10-25 09:17:49 +00:00
|
|
|
use outcome::Outcome::*;
|
2016-10-14 01:39:23 +00:00
|
|
|
use http::{StatusCode, ContentType, Method, Cookies};
|
|
|
|
|
2016-10-21 09:56:57 +00:00
|
|
|
/// Type alias for the `Outcome` of a `FromRequest` conversion.
|
2016-10-25 09:17:49 +00:00
|
|
|
pub type Outcome<T, E> = outcome::Outcome<T, (StatusCode, E), ()>;
|
2016-08-08 10:10:23 +00:00
|
|
|
|
2016-10-25 11:03:50 +00:00
|
|
|
impl<T, E> IntoOutcome<T, (StatusCode, E), ()> for Result<T, E> {
|
|
|
|
fn into_outcome(self) -> Outcome<T, E> {
|
|
|
|
match self {
|
|
|
|
Ok(val) => Success(val),
|
|
|
|
Err(val) => Failure((StatusCode::BadRequest, val))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-08 06:20:49 +00:00
|
|
|
pub trait FromRequest<'r>: Sized {
|
2016-08-08 10:10:23 +00:00
|
|
|
type Error: Debug;
|
|
|
|
|
2016-10-25 09:17:49 +00:00
|
|
|
fn from_request(request: &'r Request) -> Outcome<Self, Self::Error>;
|
2016-08-08 10:10:23 +00:00
|
|
|
}
|
|
|
|
|
2016-10-08 06:20:49 +00:00
|
|
|
impl<'r> FromRequest<'r> for &'r Request {
|
2016-08-08 10:10:23 +00:00
|
|
|
type Error = ();
|
|
|
|
|
2016-10-25 09:17:49 +00:00
|
|
|
fn from_request(request: &'r Request) -> Outcome<Self, Self::Error> {
|
|
|
|
Success(request)
|
2016-08-08 10:10:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-08 06:20:49 +00:00
|
|
|
impl<'r> FromRequest<'r> for Method {
|
2016-08-27 12:10:29 +00:00
|
|
|
type Error = ();
|
2016-08-08 10:10:23 +00:00
|
|
|
|
2016-10-25 09:17:49 +00:00
|
|
|
fn from_request(request: &'r Request) -> Outcome<Self, Self::Error> {
|
|
|
|
Success(request.method)
|
2016-08-08 10:10:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-08 06:20:49 +00:00
|
|
|
impl<'r> FromRequest<'r> for &'r Cookies {
|
2016-08-27 12:10:29 +00:00
|
|
|
type Error = ();
|
2016-10-14 01:39:23 +00:00
|
|
|
|
2016-10-25 09:17:49 +00:00
|
|
|
fn from_request(request: &'r Request) -> Outcome<Self, Self::Error> {
|
|
|
|
Success(request.cookies())
|
2016-08-08 10:48:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-08 06:20:49 +00:00
|
|
|
impl<'r> FromRequest<'r> for ContentType {
|
2016-08-27 12:10:29 +00:00
|
|
|
type Error = ();
|
|
|
|
|
2016-10-25 09:17:49 +00:00
|
|
|
fn from_request(request: &'r Request) -> Outcome<Self, Self::Error> {
|
|
|
|
Success(request.content_type())
|
2016-08-27 12:10:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-14 01:39:23 +00:00
|
|
|
impl<'r, T: FromRequest<'r>> FromRequest<'r> for Result<T, T::Error> {
|
2016-08-08 10:10:23 +00:00
|
|
|
type Error = ();
|
|
|
|
|
2016-10-25 09:17:49 +00:00
|
|
|
fn from_request(request: &'r Request) -> Outcome<Self, Self::Error> {
|
2016-10-14 01:39:23 +00:00
|
|
|
match T::from_request(request) {
|
2016-10-25 09:17:49 +00:00
|
|
|
Success(val) => Success(Ok(val)),
|
|
|
|
Failure((_, e)) => Success(Err(e)),
|
|
|
|
Forward(_) => Forward(()),
|
2016-10-14 01:39:23 +00:00
|
|
|
}
|
2016-08-08 10:10:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-14 01:39:23 +00:00
|
|
|
impl<'r, T: FromRequest<'r>> FromRequest<'r> for Option<T> {
|
2016-08-08 10:10:23 +00:00
|
|
|
type Error = ();
|
|
|
|
|
2016-10-25 09:17:49 +00:00
|
|
|
fn from_request(request: &'r Request) -> Outcome<Self, Self::Error> {
|
2016-10-14 01:39:23 +00:00
|
|
|
match T::from_request(request) {
|
2016-10-25 09:17:49 +00:00
|
|
|
Success(val) => Success(Some(val)),
|
|
|
|
Failure(_) => Success(None),
|
|
|
|
Forward(_) => Success(None),
|
2016-10-14 01:39:23 +00:00
|
|
|
}
|
2016-08-08 10:10:23 +00:00
|
|
|
}
|
|
|
|
}
|
2016-10-14 01:39:23 +00:00
|
|
|
|