diff --git a/codegen/src/decorators/route.rs b/codegen/src/decorators/route.rs index 476e235f..b2c490b8 100644 --- a/codegen/src/decorators/route.rs +++ b/codegen/src/decorators/route.rs @@ -153,7 +153,11 @@ impl RouteGenerateExt for RouteParams { fn_param_statements.push(quote_stmt!(ecx, let $ident: $ty = match $expr { Ok(v) => v, - Err(_) => return ::rocket::Response::forward(_data) + Err(e) => { + println!(" => Failed to parse '{}': {:?}", + stringify!($ident), e); + return ::rocket::Response::forward(_data) + } }; ).expect("declared param parsing statement")); } diff --git a/codegen/tests/run-pass/segments.rs b/codegen/tests/run-pass/segments.rs index 3c68fa77..f9c18980 100644 --- a/codegen/tests/run-pass/segments.rs +++ b/codegen/tests/run-pass/segments.rs @@ -10,6 +10,9 @@ fn get(a: String, b: PathBuf) -> String { format!("{}/{}", a, b.to_string_lossy()) } -fn main() { - let _ = routes![get]; +#[post("//")] +fn get2(a: String, b: Result) -> String { + format!("{}/{}", a, b.unwrap().to_string_lossy()) } + +fn main() { } diff --git a/lib/src/request/param.rs b/lib/src/request/param.rs index 3d4ba4e7..61229c53 100644 --- a/lib/src/request/param.rs +++ b/lib/src/request/param.rs @@ -1,6 +1,8 @@ use std::str::FromStr; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6, SocketAddr}; use std::path::PathBuf; +use std::fmt::Debug; + use url; use http::uri::Segments; @@ -49,7 +51,7 @@ use http::uri::Segments; /// use whichever makes sense for your application. pub trait FromParam<'a>: Sized { /// The associated error to be returned when parsing fails. - type Error; + type Error: Debug; /// Parses an instance of `Self` from a dynamic path parameter string or /// returns an `Error` if one cannot be parsed. @@ -86,6 +88,26 @@ impl_with_fromstr!(f32, f64, isize, i8, i16, i32, i64, usize, u8, u16, u32, u64, bool, IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6, SocketAddr); +impl<'a, T: FromParam<'a>> FromParam<'a> for Result { + type Error = (); + fn from_param(p: &'a str) -> Result { + Ok(match T::from_param(p) { + Ok(val) => Ok(val), + Err(e) => Err(e), + }) + } +} + +impl<'a, T: FromParam<'a>> FromParam<'a> for Option { + type Error = (); + fn from_param(p: &'a str) -> Result { + Ok(match T::from_param(p) { + Ok(val) => Some(val), + Err(_) => None + }) + } +} + /// Trait to convert _many_ dynamic path segment strings to a concrete value. /// /// This is the `..` analog to [FromParam](trait.FromParam.html), and its @@ -97,7 +119,7 @@ impl_with_fromstr!(f32, f64, isize, i8, i16, i32, i64, usize, u8, u16, u32, u64, /// implementing type. pub trait FromSegments<'a>: Sized { /// The associated error to be returned when parsing fails. - type Error; + type Error: Debug; /// Parses an instance of `Self` from many dynamic path parameter strings or /// returns an `Error` if one cannot be parsed. @@ -117,3 +139,23 @@ impl<'a> FromSegments<'a> for PathBuf { Ok(segments.collect()) } } + +impl<'a, T: FromSegments<'a>> FromSegments<'a> for Result { + type Error = (); + fn from_segments(segments: Segments<'a>) -> Result, ()> { + Ok(match T::from_segments(segments) { + Ok(val) => Ok(val), + Err(e) => Err(e), + }) + } +} + +impl<'a, T: FromSegments<'a>> FromSegments<'a> for Option { + type Error = (); + fn from_segments(segments: Segments<'a>) -> Result, ()> { + Ok(match T::from_segments(segments) { + Ok(val) => Some(val), + Err(_) => None + }) + } +}