From 6064ee875687b0d61a76ff5e1c725649a2212260 Mon Sep 17 00:00:00 2001 From: Sam Gibson Date: Sun, 16 Aug 2015 14:44:53 +1000 Subject: [PATCH] Eliminates need to box response reader I don't know how idiomatic this is for rust, but the only way I could think of to do this is with a union enum and generics. As the number of decoders should never be more than a few, this shouldn't really be a problem. --- components/net/http_loader.rs | 38 ++++++++++++++++++++++++++--------- tests/unit/net/http_loader.rs | 2 +- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index 4f60ddbc548..ee93ef2acdb 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -129,7 +129,8 @@ fn load_for_consumer(load_data: LoadData, } Ok(mut load_response) => { - send_data(&mut load_response.reader, start_chan, load_response.metadata, classifier) + let metadata = load_response.metadata.clone(); + send_data(&mut load_response, start_chan, metadata, classifier) } } } @@ -351,22 +352,39 @@ fn update_sts_list_from_response(url: &Url, response: &HttpResponse, resource_mg } } -pub struct LoadResponse { - pub reader: Box, +pub struct LoadResponse { + decoder: Decoders, pub metadata: Metadata } -impl LoadResponse { - fn new(r: Box, m: Metadata) -> LoadResponse { - LoadResponse { reader: r, metadata: m } +impl Read for LoadResponse { + #[inline] + fn read(&mut self, buf: &mut [u8]) -> io::Result { + match self.decoder { + Decoders::Gzip(ref mut d) => d.read(buf), + Decoders::Deflate(ref mut d) => d.read(buf), + Decoders::Plain(ref mut d) => d.read(buf) + } } } +impl LoadResponse { + fn new(m: Metadata, d: Decoders) -> LoadResponse { + LoadResponse { metadata: m, decoder: d } + } +} + +enum Decoders { + Gzip(GzDecoder), + Deflate(DeflateDecoder), + Plain(R) +} + pub fn load(mut load_data: LoadData, resource_mgr_chan: IpcSender, devtools_chan: Option>, request_factory: &HttpRequestFactory) - -> Result where A: HttpRequest + 'static { + -> Result, LoadError> where A: HttpRequest + 'static { // FIXME: At the time of writing this FIXME, servo didn't have any central // location for configuration. If you're reading this and such a // repository DOES exist, please update this constant to use it. @@ -580,7 +598,7 @@ pub fn load(mut load_data: LoadData, let result = GzDecoder::new(response); match result { Ok(response_decoding) => { - return Ok(LoadResponse::new(Box::new(response_decoding), metadata)); + return Ok(LoadResponse::new(metadata, Decoders::Gzip(response_decoding))); } Err(err) => { return Err(LoadError::Decoding(metadata.final_url, err.to_string())); @@ -589,10 +607,10 @@ pub fn load(mut load_data: LoadData, } Some(Encoding::Deflate) => { let response_decoding = DeflateDecoder::new(response); - return Ok(LoadResponse::new(Box::new(response_decoding), metadata)); + return Ok(LoadResponse::new(metadata, Decoders::Deflate(response_decoding))); } None => { - return Ok(LoadResponse::new(Box::new(response), metadata)); + return Ok(LoadResponse::new(metadata, Decoders::Plain(response))); } _ => return Err(LoadError::UnsupportedContentEncodings(url.clone())) } diff --git a/tests/unit/net/http_loader.rs b/tests/unit/net/http_loader.rs index b820ddd8b37..3e61ec71ed0 100644 --- a/tests/unit/net/http_loader.rs +++ b/tests/unit/net/http_loader.rs @@ -496,7 +496,7 @@ fn test_load_follows_a_redirect() { match load::(load_data, resource_mgr, None, &Factory) { Err(_) => panic!("expected to follow a redirect"), Ok(mut lr) => { - let response = read_response(&mut *lr.reader); + let response = read_response(&mut lr); assert_eq!(response, "Yay!".to_string()); } }