2

Hyper 具有将fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>HTTP 响应的内容读取到提供的&mut [u8].

Flate2 可以压缩:

let mut d = GzDecoder::new("...".as_bytes()).unwrap();
let mut s = String::new();
d.read_to_string(&mut s).unwrap();
println!("{}", s);

我试着把这两件事放在一起:

fn gunzip(r: &Response) -> String {
    let mut zs: &mut [u8] = &mut[];
    r.read(zs);
    let mut d = GzDecoder::new(zs).unwrap();
    let mut s = String::new();
    d.read_to_string(&mut s).unwrap();
    s
}

我得到了错误:

error[E0277]: the trait bound `[u8]: std::io::Read` is not satisfied
   --> tests/integration.rs:232:21
    |
232 |         let mut d = GzDecoder::new(zs).unwrap();
    |                     ^^^^^^^^^^^^^^ trait `[u8]: std::io::Read` not satisfied
    |
    = help: the following implementations were found:
    = help:   <&'a [u8] as std::io::Read>
    = note: required because of the requirements on the impl of `std::io::Read` for `&mut [u8]`
    = note: required by `<flate2::read::DecoderReader<R>>::new`

我哪里错了?


编辑:最终的工作解决方案:

fn gunzip(r: &mut Response) -> String {
    let mut buffer = Vec::new();
    let _ = r.read_to_end(&mut buffer).unwrap();
    let mut d = GzDecoder::new(buffer.as_slice()).unwrap();
    let mut s = String::new();
    d.read_to_string(&mut s).unwrap();
    s
}
4

2 回答 2

1

这是另一种无需使用其他缓冲区即可完成的方法:

extern crate hyper;
extern crate flate2;

use std::io::Read;

use hyper::client::Client;
use hyper::header::{Headers, AcceptEncoding, Encoding, qitem};

use flate2::read::GzDecoder;

fn main() {
    let c = Client::new();

    let mut req = c.get("http://httpbin.org/gzip");
    let mut headers = Headers::new();
    headers.set(
        AcceptEncoding(vec![qitem(Encoding::Gzip)])
    );
    req = req.headers(headers);

    let res = req.send().unwrap();
    let mut decoder = GzDecoder::new(res).unwrap();
    let mut buf = String::new();

    let _ = decoder.read_to_string(&mut buf);
    println!("{}", buf);
}

此示例使用gzip来自 HTTPBIN 的端点来测试是否Response可以在GzDecoder.

我的 Cargo 文件中使用的依赖项:

[dependencies]
hyper = "0.9"
flate2 = "0.2"

PS这些unwrap()电话是为了简洁起见:)

于 2016-10-28T06:47:30.940 回答
1

参数 toGzDecoder::new是用泛型类型定义的,因此 Rust 不会执行一些在预期固定类型时会发生的转换。

您可以通过取消引用可变切片然后引用结果来将可变切片转换为不可变切片。

let mut d = GzDecoder::new(&*zs).unwrap();
于 2016-10-28T04:59:27.947 回答