Rocket

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit fe59a7fe38a0835bccdeb795fe775862332cc183
parent d9bfc9b1040cb81f9db45b0c8116669b03c98c50
Author: Sergio Benitez <sb@sergio.bz>
Date:   Fri, 10 Aug 2018 04:42:30 -0700

Use better types for 'Error' associated types.

Diffstat:
Mcore/http/src/cookies.rs | 6+++---
Mcore/lib/src/data/from_data.rs | 7++++---
Mcore/lib/src/request/from_request.rs | 55+++++++++++++++++++++++++++++--------------------------
Mcore/lib/src/request/param.rs | 2+-
Mexamples/request_guard/src/main.rs | 16+++++-----------
Mexamples/request_local_state/src/main.rs | 2+-
Mexamples/session/src/main.rs | 6+++---
7 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/core/http/src/cookies.rs b/core/http/src/cookies.rs @@ -56,7 +56,7 @@ use Header; /// [private cookie]: /rocket/http/enum.Cookies.html#private-cookies /// /// ```rust -/// # #![feature(plugin, decl_macro)] +/// # #![feature(plugin, decl_macro, never_type)] /// # #![plugin(rocket_codegen)] /// # extern crate rocket; /// # @@ -68,9 +68,9 @@ use Header; /// struct User(usize); /// /// impl<'a, 'r> FromRequest<'a, 'r> for User { -/// type Error = (); +/// type Error = !; /// -/// fn from_request(request: &'a Request<'r>) -> request::Outcome<User, ()> { +/// fn from_request(request: &'a Request<'r>) -> request::Outcome<User, !> { /// request.cookies() /// .get_private("user_id") /// .and_then(|cookie| cookie.value().parse().ok()) diff --git a/core/lib/src/data/from_data.rs b/core/lib/src/data/from_data.rs @@ -226,14 +226,15 @@ pub trait FromData: Sized { /// The identity implementation of `FromData`. Always returns `Success`. impl FromData for Data { - type Error = (); + type Error = !; + fn from_data(_: &Request, data: Data) -> Outcome<Self, Self::Error> { Success(data) } } impl<T: FromData> FromData for Result<T, T::Error> { - type Error = (); + type Error = !; fn from_data(request: &Request, data: Data) -> Outcome<Self, Self::Error> { match T::from_data(request, data) { @@ -245,7 +246,7 @@ impl<T: FromData> FromData for Result<T, T::Error> { } impl<T: FromData> FromData for Option<T> { - type Error = (); + type Error = !; fn from_data(request: &Request, data: Data) -> Outcome<Self, Self::Error> { match T::from_data(request, data) { diff --git a/core/lib/src/request/from_request.rs b/core/lib/src/request/from_request.rs @@ -181,21 +181,24 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> { /// key == "valid_api_key" /// } /// +/// #[derive(Debug)] +/// enum ApiKeyError { +/// BadCount, +/// Missing, +/// Invalid, +/// } +/// /// impl<'a, 'r> FromRequest<'a, 'r> for ApiKey { -/// type Error = (); +/// type Error = ApiKeyError; /// -/// fn from_request(request: &'a Request<'r>) -> request::Outcome<ApiKey, ()> { +/// fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> { /// let keys: Vec<_> = request.headers().get("x-api-key").collect(); -/// if keys.len() != 1 { -/// return Outcome::Failure((Status::BadRequest, ())); -/// } -/// -/// let key = keys[0]; -/// if !is_valid(keys[0]) { -/// return Outcome::Forward(()); +/// match keys.len() { +/// 0 => Outcome::Failure((Status::BadRequest, ApiKeyError::Missing)), +/// 1 if is_valid(keys[0]) => Outcome::Success(ApiKey(keys[0].to_string())), +/// 1 => Outcome::Failure((Status::BadRequest, ApiKeyError::Invalid)), +/// _ => Outcome::Failure((Status::BadRequest, ApiKeyError::BadCount)), /// } -/// -/// return Outcome::Success(ApiKey(key.to_string())); /// } /// } /// @@ -219,7 +222,7 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> { /// routes (`admin_dashboard` and `user_dashboard`): /// /// ```rust -/// # #![feature(plugin, decl_macro)] +/// # #![feature(plugin, decl_macro, never_type)] /// # #![plugin(rocket_codegen)] /// # extern crate rocket; /// # @@ -282,7 +285,7 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> { /// used, as illustrated below: /// /// ```rust -/// # #![feature(plugin, decl_macro)] +/// # #![feature(plugin, decl_macro, never_type)] /// # #![plugin(rocket_codegen)] /// # extern crate rocket; /// # @@ -305,9 +308,9 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> { /// # struct Admin<'a> { user: &'a User }; /// # /// impl<'a, 'r> FromRequest<'a, 'r> for &'a User { -/// type Error = (); +/// type Error = !; /// -/// fn from_request(request: &'a Request<'r>) -> request::Outcome<&'a User, ()> { +/// fn from_request(request: &'a Request<'r>) -> request::Outcome<&'a User, !> { /// // This closure will execute at most once per request, regardless of /// // the number of times the `User` guard is executed. /// let user_result = request.local_cache(|| { @@ -323,9 +326,9 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> { /// } /// /// impl<'a, 'r> FromRequest<'a, 'r> for Admin<'a> { -/// type Error = (); +/// type Error = !; /// -/// fn from_request(request: &'a Request<'r>) -> request::Outcome<Admin<'a>, ()> { +/// fn from_request(request: &'a Request<'r>) -> request::Outcome<Admin<'a>, !> { /// let user = request.guard::<&User>()?; /// /// if user.is_admin { @@ -356,7 +359,7 @@ pub trait FromRequest<'a, 'r>: Sized { } impl<'a, 'r> FromRequest<'a, 'r> for Method { - type Error = (); + type Error = !; fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> { Success(request.method()) @@ -364,7 +367,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for Method { } impl<'a, 'r> FromRequest<'a, 'r> for &'a Origin<'a> { - type Error = (); + type Error = !; fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> { Success(request.uri()) @@ -372,7 +375,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for &'a Origin<'a> { } impl<'a, 'r> FromRequest<'a, 'r> for &'r Route { - type Error = (); + type Error = !; fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> { match request.route() { @@ -383,7 +386,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for &'r Route { } impl<'a, 'r> FromRequest<'a, 'r> for Cookies<'a> { - type Error = (); + type Error = !; fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> { Success(request.cookies()) @@ -391,7 +394,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for Cookies<'a> { } impl<'a, 'r> FromRequest<'a, 'r> for &'a Accept { - type Error = (); + type Error = !; fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> { match request.accept() { @@ -402,7 +405,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for &'a Accept { } impl<'a, 'r> FromRequest<'a, 'r> for &'a ContentType { - type Error = (); + type Error = !; fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> { match request.content_type() { @@ -413,7 +416,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for &'a ContentType { } impl<'a, 'r> FromRequest<'a, 'r> for SocketAddr { - type Error = (); + type Error = !; fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> { match request.remote() { @@ -424,7 +427,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for SocketAddr { } impl<'a, 'r, T: FromRequest<'a, 'r>> FromRequest<'a, 'r> for Result<T, T::Error> { - type Error = (); + type Error = T::Error; fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> { match T::from_request(request) { @@ -436,7 +439,7 @@ impl<'a, 'r, T: FromRequest<'a, 'r>> FromRequest<'a, 'r> for Result<T, T::Error> } impl<'a, 'r, T: FromRequest<'a, 'r>> FromRequest<'a, 'r> for Option<T> { - type Error = (); + type Error = !; fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> { match T::from_request(request) { diff --git a/core/lib/src/request/param.rs b/core/lib/src/request/param.rs @@ -202,7 +202,7 @@ pub trait FromParam<'a>: Sized { } impl<'a> FromParam<'a> for &'a RawStr { - type Error = (); + type Error = !; #[inline(always)] fn from_param(param: &'a RawStr) -> Result<&'a RawStr, Self::Error> { diff --git a/examples/request_guard/src/main.rs b/examples/request_guard/src/main.rs @@ -1,31 +1,25 @@ -#![feature(plugin, decl_macro)] +#![feature(plugin, decl_macro, never_type)] #![plugin(rocket_codegen)] extern crate rocket; -use std::fmt; use rocket::request::{self, Request, FromRequest}; use rocket::outcome::Outcome::*; #[derive(Debug)] struct HeaderCount(usize); -impl fmt::Display for HeaderCount { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0) - } -} - impl<'a, 'r> FromRequest<'a, 'r> for HeaderCount { - type Error = (); - fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, ()> { + type Error = !; + + fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, !> { Success(HeaderCount(request.headers().len())) } } #[get("/")] fn header_count(header_count: HeaderCount) -> String { - format!("Your request contained {} headers!", header_count) + format!("Your request contained {} headers!", header_count.0) } fn rocket() -> rocket::Rocket { diff --git a/examples/request_local_state/src/main.rs b/examples/request_local_state/src/main.rs @@ -1,4 +1,4 @@ -#![feature(plugin, decl_macro)] +#![feature(plugin, decl_macro, never_type)] #![plugin(rocket_codegen)] extern crate rocket; diff --git a/examples/session/src/main.rs b/examples/session/src/main.rs @@ -1,4 +1,4 @@ -#![feature(plugin, decl_macro)] +#![feature(plugin, decl_macro, never_type)] #![plugin(rocket_codegen)] extern crate rocket_contrib; @@ -24,9 +24,9 @@ struct Login { struct User(usize); impl<'a, 'r> FromRequest<'a, 'r> for User { - type Error = (); + type Error = !; - fn from_request(request: &'a Request<'r>) -> request::Outcome<User, ()> { + fn from_request(request: &'a Request<'r>) -> request::Outcome<User, !> { request.cookies() .get_private("user_id") .and_then(|cookie| cookie.value().parse().ok())