1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//! [`io::Read`] implementations for [`minreq`].
use std::io;
/// A wrapper that implements [`io::Read`] on a [`minreq::ResponseLazy`].
pub enum ResponseLazyReader {
Request(minreq::Request),
Response(minreq::ResponseLazy),
Complete(Result<(), String>),
}
impl From<minreq::Request> for ResponseLazyReader {
fn from(request: minreq::Request) -> ResponseLazyReader {
ResponseLazyReader::Request(request)
}
}
impl From<minreq::ResponseLazy> for ResponseLazyReader {
fn from(response: minreq::ResponseLazy) -> ResponseLazyReader {
ResponseLazyReader::Response(response)
}
}
impl io::Read for ResponseLazyReader {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
use ResponseLazyReader::{Complete, Request, Response};
// Zero-sized buffer. This should never happen.
if buf.is_empty() {
return Ok(0);
}
loop {
match self {
// Launch a lazy response for this request
Request(request) => match request.clone().send_lazy() {
Ok(response) => *self = Response(response),
Err(error) => {
let error = Err(format!("download request failed: {:?}", error));
*self = Complete(error);
}
},
// Read from the response
Response(response) => {
for (i, buf_byte) in buf.iter_mut().enumerate() {
match response.next() {
// Load a byte into the buffer.
Some(Ok((byte, _length))) => {
*buf_byte = byte;
}
// The whole response has been processed.
None => {
*self = Complete(Ok(()));
return Ok(i);
}
// The response is corrupted.
Some(Err(error)) => {
let error = format!("download response failed: {:?}", error);
*self = Complete(Err(error.clone()));
return Err(io::Error::other(error));
}
}
}
return Ok(buf.len());
}
Complete(result) => {
return match result {
// Return a zero-byte read for download success and EOF.
Ok(()) => Ok(0),
// Keep returning the download error,
Err(error) => Err(io::Error::other(error.clone())),
};
}
}
}
}
}