use std::io::Write;
pub struct ChunkedWrite<W: Write>(W);
impl<W: Write> ChunkedWrite<W> {
pub fn new(sink: W) -> Self {
ChunkedWrite(sink)
}
fn send(&mut self, data: &[u8]) -> std::io::Result<()> {
try!(write!(self.0, "{:x}\r\n", data.len()));
try!(self.0.write_all(data));
try!(write!(self.0, "\r\n"));
Ok(())
}
}
impl<W: Write> Write for ChunkedWrite<W> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
try!(self.send(buf));
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> { self.0.flush() }
}
impl<W: Write> Drop for ChunkedWrite<W> {
fn drop(&mut self) {
self.send(&[]).is_ok();
self.flush().is_ok();
}
}
#[cfg(test)]
mod test {
use super::*;
use std::io::Write;
#[test]
fn test_chunked_write() {
let mut buf = [0; 32];
{
let mut w = ChunkedWrite::new(&mut buf[..]);
w.write_all(b"abc def").unwrap();
w.write_all(b"gh\nijklmno").unwrap();
}
assert_eq!(&buf[..], b"7\r\nabc def\r\na\r\ngh\nijklmno\r\n0\r\n\r\n");
}
}