rust-postgres/postgres/src/copy_out_reader.rs

62 lines
1.6 KiB
Rust
Raw Normal View History

2019-12-15 23:58:50 +00:00
use crate::Rt;
2018-12-29 05:01:10 +00:00
use bytes::{Buf, Bytes};
use futures::StreamExt;
2018-12-29 05:01:10 +00:00
use std::io::{self, BufRead, Cursor, Read};
2019-08-04 01:09:27 +00:00
use std::pin::Pin;
2019-11-30 21:17:23 +00:00
use tokio_postgres::{CopyOutStream, Error};
2018-12-29 05:01:10 +00:00
2019-03-31 03:58:01 +00:00
/// The reader returned by the `copy_out` method.
pub struct CopyOutReader<'a> {
2019-12-15 23:58:50 +00:00
runtime: Rt<'a>,
stream: Pin<Box<CopyOutStream>>,
2018-12-29 05:01:10 +00:00
cur: Cursor<Bytes>,
}
impl<'a> CopyOutReader<'a> {
pub(crate) fn new(
2019-12-15 23:58:50 +00:00
mut runtime: Rt<'a>,
stream: CopyOutStream,
) -> Result<CopyOutReader<'a>, Error> {
let mut stream = Box::pin(stream);
let cur = match runtime.block_on(stream.next()) {
2018-12-29 05:01:10 +00:00
Some(Ok(cur)) => cur,
Some(Err(e)) => return Err(e),
None => Bytes::new(),
};
Ok(CopyOutReader {
runtime,
stream,
2018-12-29 05:01:10 +00:00
cur: Cursor::new(cur),
})
}
}
impl Read for CopyOutReader<'_> {
2018-12-29 05:01:10 +00:00
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let b = self.fill_buf()?;
let len = usize::min(buf.len(), b.len());
buf[..len].copy_from_slice(&b[..len]);
self.consume(len);
Ok(len)
}
}
impl BufRead for CopyOutReader<'_> {
2018-12-29 05:01:10 +00:00
fn fill_buf(&mut self) -> io::Result<&[u8]> {
if self.cur.remaining() == 0 {
match self.runtime.block_on(self.stream.next()) {
2018-12-29 05:01:10 +00:00
Some(Ok(cur)) => self.cur = Cursor::new(cur),
Some(Err(e)) => return Err(io::Error::new(io::ErrorKind::Other, e)),
None => {}
};
}
Ok(Buf::bytes(&self.cur))
}
fn consume(&mut self, amt: usize) {
self.cur.advance(amt);
}
}