mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
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.
This commit is contained in:
parent
879b058be2
commit
6064ee8756
2 changed files with 29 additions and 11 deletions
|
@ -129,7 +129,8 @@ fn load_for_consumer(load_data: LoadData,
|
||||||
|
|
||||||
}
|
}
|
||||||
Ok(mut load_response) => {
|
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 struct LoadResponse<R: HttpResponse> {
|
||||||
pub reader: Box<Read>,
|
decoder: Decoders<R>,
|
||||||
pub metadata: Metadata
|
pub metadata: Metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LoadResponse {
|
impl<R: HttpResponse> Read for LoadResponse<R> {
|
||||||
fn new(r: Box<Read>, m: Metadata) -> LoadResponse {
|
#[inline]
|
||||||
LoadResponse { reader: r, metadata: m }
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
|
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<R: HttpResponse> LoadResponse<R> {
|
||||||
|
fn new(m: Metadata, d: Decoders<R>) -> LoadResponse<R> {
|
||||||
|
LoadResponse { metadata: m, decoder: d }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Decoders<R: Read> {
|
||||||
|
Gzip(GzDecoder<R>),
|
||||||
|
Deflate(DeflateDecoder<R>),
|
||||||
|
Plain(R)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load<A>(mut load_data: LoadData,
|
pub fn load<A>(mut load_data: LoadData,
|
||||||
resource_mgr_chan: IpcSender<ControlMsg>,
|
resource_mgr_chan: IpcSender<ControlMsg>,
|
||||||
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
|
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
|
||||||
request_factory: &HttpRequestFactory<R=A>)
|
request_factory: &HttpRequestFactory<R=A>)
|
||||||
-> Result<LoadResponse, LoadError> where A: HttpRequest + 'static {
|
-> Result<LoadResponse<A::R>, LoadError> where A: HttpRequest + 'static {
|
||||||
// FIXME: At the time of writing this FIXME, servo didn't have any central
|
// 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
|
// location for configuration. If you're reading this and such a
|
||||||
// repository DOES exist, please update this constant to use it.
|
// repository DOES exist, please update this constant to use it.
|
||||||
|
@ -580,7 +598,7 @@ pub fn load<A>(mut load_data: LoadData,
|
||||||
let result = GzDecoder::new(response);
|
let result = GzDecoder::new(response);
|
||||||
match result {
|
match result {
|
||||||
Ok(response_decoding) => {
|
Ok(response_decoding) => {
|
||||||
return Ok(LoadResponse::new(Box::new(response_decoding), metadata));
|
return Ok(LoadResponse::new(metadata, Decoders::Gzip(response_decoding)));
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return Err(LoadError::Decoding(metadata.final_url, err.to_string()));
|
return Err(LoadError::Decoding(metadata.final_url, err.to_string()));
|
||||||
|
@ -589,10 +607,10 @@ pub fn load<A>(mut load_data: LoadData,
|
||||||
}
|
}
|
||||||
Some(Encoding::Deflate) => {
|
Some(Encoding::Deflate) => {
|
||||||
let response_decoding = DeflateDecoder::new(response);
|
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 => {
|
None => {
|
||||||
return Ok(LoadResponse::new(Box::new(response), metadata));
|
return Ok(LoadResponse::new(metadata, Decoders::Plain(response)));
|
||||||
}
|
}
|
||||||
_ => return Err(LoadError::UnsupportedContentEncodings(url.clone()))
|
_ => return Err(LoadError::UnsupportedContentEncodings(url.clone()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -496,7 +496,7 @@ fn test_load_follows_a_redirect() {
|
||||||
match load::<MockRequest>(load_data, resource_mgr, None, &Factory) {
|
match load::<MockRequest>(load_data, resource_mgr, None, &Factory) {
|
||||||
Err(_) => panic!("expected to follow a redirect"),
|
Err(_) => panic!("expected to follow a redirect"),
|
||||||
Ok(mut lr) => {
|
Ok(mut lr) => {
|
||||||
let response = read_response(&mut *lr.reader);
|
let response = read_response(&mut lr);
|
||||||
assert_eq!(response, "Yay!".to_string());
|
assert_eq!(response, "Yay!".to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue