From f37880d89c098f8a4fa03a7a003e3d33064a7bff Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Fri, 4 May 2018 11:44:22 -0700 Subject: [PATCH] refactor Responder trait --- src/body.rs | 4 ++-- src/error.rs | 2 +- src/fs.rs | 16 +++++++-------- src/handler.rs | 50 +++++++++++++++++++++++++++------------------ src/httpresponse.rs | 14 ++++++------- src/json.rs | 4 ++-- src/test.rs | 6 +++--- src/with.rs | 22 +++++++++----------- 8 files changed, 63 insertions(+), 55 deletions(-) diff --git a/src/body.rs b/src/body.rs index cf54361d6..063c93ac5 100644 --- a/src/body.rs +++ b/src/body.rs @@ -257,8 +257,8 @@ impl Responder for Binary { type Item = HttpResponse; type Error = Error; - fn respond_to(self, _: HttpRequest) -> Result { - Ok(HttpResponse::Ok() + fn respond_to(self, req: &HttpRequest) -> Result { + Ok(HttpResponse::build_from(req) .content_type("application/octet-stream") .body(self)) } diff --git a/src/error.rs b/src/error.rs index cc29fe638..5ef2ddd74 100644 --- a/src/error.rs +++ b/src/error.rs @@ -642,7 +642,7 @@ where type Item = HttpResponse; type Error = Error; - fn respond_to(self, _: HttpRequest) -> Result { + fn respond_to(self, _: &HttpRequest) -> Result { Err(self.into()) } } diff --git a/src/fs.rs b/src/fs.rs index 348a99792..de1a60a3c 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -161,7 +161,7 @@ impl DerefMut for NamedFile { } /// Returns true if `req` has no `If-Match` header or one which matches `etag`. -fn any_match(etag: Option<&header::EntityTag>, req: &HttpRequest) -> bool { +fn any_match(etag: Option<&header::EntityTag>, req: &HttpRequest) -> bool { match req.get_header::() { None | Some(header::IfMatch::Any) => true, Some(header::IfMatch::Items(ref items)) => { @@ -178,7 +178,7 @@ fn any_match(etag: Option<&header::EntityTag>, req: &HttpRequest) -> bool { } /// Returns true if `req` doesn't have an `If-None-Match` header matching `req`. -fn none_match(etag: Option<&header::EntityTag>, req: &HttpRequest) -> bool { +fn none_match(etag: Option<&header::EntityTag>, req: &HttpRequest) -> bool { match req.get_header::() { Some(header::IfNoneMatch::Any) => false, Some(header::IfNoneMatch::Items(ref items)) => { @@ -199,7 +199,7 @@ impl Responder for NamedFile { type Item = HttpResponse; type Error = io::Error; - fn respond_to(self, req: HttpRequest) -> Result { + fn respond_to(self, req: &HttpRequest) -> Result { if self.status_code != StatusCode::OK { let mut resp = HttpResponse::build(self.status_code); resp.if_some(self.path().extension(), |ext, resp| { @@ -244,7 +244,7 @@ impl Responder for NamedFile { let last_modified = self.last_modified(); // check preconditions - let precondition_failed = if !any_match(etag.as_ref(), &req) { + let precondition_failed = if !any_match(etag.as_ref(), req) { true } else if let (Some(ref m), Some(header::IfUnmodifiedSince(ref since))) = (last_modified, req.get_header()) @@ -255,7 +255,7 @@ impl Responder for NamedFile { }; // check last modified - let not_modified = if !none_match(etag.as_ref(), &req) { + let not_modified = if !none_match(etag.as_ref(), req) { true } else if let (Some(ref m), Some(header::IfModifiedSince(ref since))) = (last_modified, req.get_header()) @@ -612,7 +612,7 @@ impl Handler for StaticFiles { HttpResponse::Found() .header(header::LOCATION, new_path.as_str()) .finish() - .respond_to(req.drop_state()) + .respond_to(&req) } else if self.show_index { let dir = Directory::new(self.directory.clone(), path); Ok((*self.renderer)(&dir, &req)?.into()) @@ -622,8 +622,8 @@ impl Handler for StaticFiles { } else { NamedFile::open(path)? .set_cpu_pool(self.cpu_pool.clone()) - .respond_to(req.drop_state())? - .respond_to(req.drop_state()) + .respond_to(&req)? + .respond_to(&req) } } } diff --git a/src/handler.rs b/src/handler.rs index 632d63abb..7b88248bf 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -29,7 +29,9 @@ pub trait Responder { type Error: Into; /// Convert itself to `AsyncResult` or `Error`. - fn respond_to(self, req: HttpRequest) -> Result; + fn respond_to( + self, req: &HttpRequest, + ) -> Result; } /// Trait implemented by types that can be extracted from request. @@ -96,7 +98,9 @@ where type Item = AsyncResult; type Error = Error; - fn respond_to(self, req: HttpRequest) -> Result, Error> { + fn respond_to( + self, req: &HttpRequest, + ) -> Result, Error> { match self { Either::A(a) => match a.respond_to(req) { Ok(val) => Ok(val.into()), @@ -232,7 +236,7 @@ impl AsyncResult { /// Send error #[inline] - pub fn error>(err: R) -> AsyncResult { + pub fn err>(err: R) -> AsyncResult { AsyncResult(Some(AsyncResultItem::Err(err.into()))) } @@ -262,7 +266,9 @@ impl Responder for AsyncResult { type Item = AsyncResult; type Error = Error; - fn respond_to(self, _: HttpRequest) -> Result, Error> { + fn respond_to( + self, _: &HttpRequest, + ) -> Result, Error> { Ok(self) } } @@ -272,7 +278,9 @@ impl Responder for HttpResponse { type Error = Error; #[inline] - fn respond_to(self, _: HttpRequest) -> Result, Error> { + fn respond_to( + self, _: &HttpRequest, + ) -> Result, Error> { Ok(AsyncResult(Some(AsyncResultItem::Ok(self)))) } } @@ -288,7 +296,7 @@ impl> Responder for Result { type Item = ::Item; type Error = Error; - fn respond_to(self, req: HttpRequest) -> Result { + fn respond_to(self, req: &HttpRequest) -> Result { match self { Ok(val) => match val.respond_to(req) { Ok(val) => Ok(val), @@ -350,9 +358,12 @@ where type Error = Error; #[inline] - fn respond_to(self, req: HttpRequest) -> Result, Error> { + fn respond_to( + self, req: &HttpRequest, + ) -> Result, Error> { + let req = req.clone(); let fut = self.map_err(|e| e.into()) - .then(move |r| match r.respond_to(req) { + .then(move |r| match r.respond_to(&req) { Ok(reply) => match reply.into().into() { AsyncResultItem::Ok(resp) => ok(resp), _ => panic!("Nested async replies are not supported"), @@ -363,7 +374,7 @@ where } } -/// Trait defines object that could be registered as resource route +// /// Trait defines object that could be registered as resource route pub(crate) trait RouteHandler: 'static { fn handle(&mut self, req: HttpRequest) -> AsyncResult; } @@ -400,10 +411,9 @@ where S: 'static, { fn handle(&mut self, req: HttpRequest) -> AsyncResult { - let req2 = req.drop_state(); - match self.h.handle(req).respond_to(req2) { + match self.h.handle(req.clone()).respond_to(&req) { Ok(reply) => reply.into(), - Err(err) => AsyncResult::ok(err.into()), + Err(err) => AsyncResult::err(err.into()), } } } @@ -446,16 +456,16 @@ where S: 'static, { fn handle(&mut self, req: HttpRequest) -> AsyncResult { - let req2 = req.drop_state(); - let fut = (self.h)(req).map_err(|e| e.into()).then(move |r| { - match r.respond_to(req2) { + let fut = (self.h)(req.clone()) + .map_err(|e| e.into()) + .then(move |r| match r.respond_to(&req) { Ok(reply) => match reply.into().into() { - AsyncResultItem::Ok(resp) => ok(resp), - _ => panic!("Nested async replies are not supported"), + AsyncResultItem::Ok(resp) => Either::A(ok(resp)), + AsyncResultItem::Err(e) => Either::A(err(e)), + AsyncResultItem::Future(fut) => Either::B(fut), }, - Err(e) => err(e), - } - }); + Err(e) => Either::A(err(e)), + }); AsyncResult::async(Box::new(fut)) } } diff --git a/src/httpresponse.rs b/src/httpresponse.rs index f776612d6..00db2775e 100644 --- a/src/httpresponse.rs +++ b/src/httpresponse.rs @@ -636,7 +636,7 @@ impl Responder for HttpResponseBuilder { type Error = Error; #[inline] - fn respond_to(mut self, _: HttpRequest) -> Result { + fn respond_to(mut self, _: &HttpRequest) -> Result { Ok(self.finish()) } } @@ -653,7 +653,7 @@ impl Responder for &'static str { type Item = HttpResponse; type Error = Error; - fn respond_to(self, req: HttpRequest) -> Result { + fn respond_to(self, req: &HttpRequest) -> Result { Ok(req.build_response(StatusCode::OK) .content_type("text/plain; charset=utf-8") .body(self)) @@ -672,7 +672,7 @@ impl Responder for &'static [u8] { type Item = HttpResponse; type Error = Error; - fn respond_to(self, req: HttpRequest) -> Result { + fn respond_to(self, req: &HttpRequest) -> Result { Ok(req.build_response(StatusCode::OK) .content_type("application/octet-stream") .body(self)) @@ -691,7 +691,7 @@ impl Responder for String { type Item = HttpResponse; type Error = Error; - fn respond_to(self, req: HttpRequest) -> Result { + fn respond_to(self, req: &HttpRequest) -> Result { Ok(req.build_response(StatusCode::OK) .content_type("text/plain; charset=utf-8") .body(self)) @@ -710,7 +710,7 @@ impl<'a> Responder for &'a String { type Item = HttpResponse; type Error = Error; - fn respond_to(self, req: HttpRequest) -> Result { + fn respond_to(self, req: &HttpRequest) -> Result { Ok(req.build_response(StatusCode::OK) .content_type("text/plain; charset=utf-8") .body(self)) @@ -729,7 +729,7 @@ impl Responder for Bytes { type Item = HttpResponse; type Error = Error; - fn respond_to(self, req: HttpRequest) -> Result { + fn respond_to(self, req: &HttpRequest) -> Result { Ok(req.build_response(StatusCode::OK) .content_type("application/octet-stream") .body(self)) @@ -748,7 +748,7 @@ impl Responder for BytesMut { type Item = HttpResponse; type Error = Error; - fn respond_to(self, req: HttpRequest) -> Result { + fn respond_to(self, req: &HttpRequest) -> Result { Ok(req.build_response(StatusCode::OK) .content_type("application/octet-stream") .body(self)) diff --git a/src/json.rs b/src/json.rs index 27c99c649..6711de391 100644 --- a/src/json.rs +++ b/src/json.rs @@ -118,7 +118,7 @@ impl Responder for Json { type Item = HttpResponse; type Error = Error; - fn respond_to(self, req: HttpRequest) -> Result { + fn respond_to(self, req: &HttpRequest) -> Result { let body = serde_json::to_string(&self.0)?; Ok(req.build_response(StatusCode::OK) @@ -351,7 +351,7 @@ mod tests { let json = Json(MyObject { name: "test".to_owned(), }); - let resp = json.respond_to(HttpRequest::default()).unwrap(); + let resp = json.respond_to(&HttpRequest::default()).unwrap(); assert_eq!( resp.headers().get(header::CONTENT_TYPE).unwrap(), "application/json" diff --git a/src/test.rs b/src/test.rs index 57edcbf0a..c712edd61 100644 --- a/src/test.rs +++ b/src/test.rs @@ -478,7 +478,7 @@ impl TestRequest<()> { } } -impl TestRequest { +impl TestRequest { /// Start HttpRequest build process with application state pub fn with_state(state: S) -> TestRequest { TestRequest { @@ -597,7 +597,7 @@ impl TestRequest { let req = self.finish(); let resp = h.handle(req.clone()); - match resp.respond_to(req.drop_state()) { + match resp.respond_to(&req) { Ok(resp) => match resp.into().into() { AsyncResultItem::Ok(resp) => Ok(resp), AsyncResultItem::Err(err) => Err(err), @@ -623,7 +623,7 @@ impl TestRequest { let mut core = Core::new().unwrap(); match core.run(fut) { - Ok(r) => match r.respond_to(req.drop_state()) { + Ok(r) => match r.respond_to(&req) { Ok(reply) => match reply.into().into() { AsyncResultItem::Ok(resp) => Ok(resp), _ => panic!("Nested async replies are not supported"), diff --git a/src/with.rs b/src/with.rs index 0f7d07744..fa3d7d802 100644 --- a/src/with.rs +++ b/src/with.rs @@ -97,7 +97,7 @@ where match fut.poll() { Ok(Async::Ready(resp)) => AsyncResult::ok(resp), Ok(Async::NotReady) => AsyncResult::async(Box::new(fut)), - Err(e) => AsyncResult::error::(e), + Err(e) => AsyncResult::err(e), } } } @@ -151,7 +151,7 @@ where }; let hnd: &mut F = unsafe { &mut *self.hnd.get() }; - let item = match (*hnd)(item).respond_to(self.req.drop_state()) { + let item = match (*hnd)(item).respond_to(&self.req) { Ok(item) => item.into(), Err(e) => return Err(e.into()), }; @@ -288,7 +288,7 @@ where }; let hnd: &mut F = unsafe { &mut *self.hnd.get() }; - match (*hnd)(item1, item2).respond_to(self.req.drop_state()) { + match (*hnd)(item1, item2).respond_to(&self.req) { Ok(item) => match item.into().into() { AsyncResultItem::Err(err) => return Err(err), AsyncResultItem::Ok(resp) => return Ok(Async::Ready(resp)), @@ -316,7 +316,7 @@ where }; let hnd: &mut F = unsafe { &mut *self.hnd.get() }; - match (*hnd)(item, item2).respond_to(self.req.drop_state()) { + match (*hnd)(item, item2).respond_to(&self.req) { Ok(item) => match item.into().into() { AsyncResultItem::Err(err) => return Err(err), AsyncResultItem::Ok(resp) => return Ok(Async::Ready(resp)), @@ -338,9 +338,7 @@ where }; let hnd: &mut F = unsafe { &mut *self.hnd.get() }; - let item = match (*hnd)(self.item.take().unwrap(), item) - .respond_to(self.req.drop_state()) - { + let item = match (*hnd)(self.item.take().unwrap(), item).respond_to(&self.req) { Ok(item) => item.into(), Err(err) => return Err(err.into()), }; @@ -424,7 +422,7 @@ where match fut.poll() { Ok(Async::Ready(resp)) => AsyncResult::ok(resp), Ok(Async::NotReady) => AsyncResult::async(Box::new(fut)), - Err(e) => AsyncResult::error(e), + Err(e) => AsyncResult::err(e), } } } @@ -505,7 +503,7 @@ where }; let hnd: &mut F = unsafe { &mut *self.hnd.get() }; - match (*hnd)(item1, item2, item3).respond_to(self.req.drop_state()) { + match (*hnd)(item1, item2, item3).respond_to(&self.req) { Ok(item) => match item.into().into() { AsyncResultItem::Err(err) => return Err(err), AsyncResultItem::Ok(resp) => return Ok(Async::Ready(resp)), @@ -545,7 +543,7 @@ where }; let hnd: &mut F = unsafe { &mut *self.hnd.get() }; match (*hnd)(self.item1.take().unwrap(), item2, item3) - .respond_to(self.req.drop_state()) + .respond_to(&self.req) { Ok(item) => match item.into().into() { AsyncResultItem::Err(err) => return Err(err), @@ -578,7 +576,7 @@ where }; let hnd: &mut F = unsafe { &mut *self.hnd.get() }; match (*hnd)(self.item1.take().unwrap(), item, item3) - .respond_to(self.req.drop_state()) + .respond_to(&self.req) { Ok(item) => match item.into().into() { AsyncResultItem::Err(err) => return Err(err), @@ -605,7 +603,7 @@ where self.item1.take().unwrap(), self.item2.take().unwrap(), item, - ).respond_to(self.req.drop_state()) + ).respond_to(&self.req) { Ok(item) => item.into(), Err(err) => return Err(err.into()),