2019-01-21 14:03:30 -05:00
|
|
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
2019-09-10 00:59:40 -04:00
|
|
|
use crate::resources::DenoAsyncWrite;
|
|
|
|
use deno::ErrBox;
|
2018-10-19 16:10:25 -04:00
|
|
|
use futures::{Future, Poll};
|
2019-09-10 00:59:40 -04:00
|
|
|
use std::mem;
|
2018-10-19 16:10:25 -04:00
|
|
|
|
|
|
|
/// A future used to write some data to a stream.
|
|
|
|
///
|
|
|
|
/// This is created by the [`write`] top-level method.
|
|
|
|
///
|
|
|
|
/// [`write`]: fn.write.html
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Write<A, T> {
|
|
|
|
state: State<A, T>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
enum State<A, T> {
|
|
|
|
Pending { a: A, buf: T },
|
|
|
|
Empty,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Creates a future that will write some of the buffer `buf` to
|
|
|
|
/// the stream `a` provided.
|
|
|
|
///
|
|
|
|
/// Any error which happens during writing will cause both the stream and the
|
|
|
|
/// buffer to get destroyed.
|
|
|
|
pub fn write<A, T>(a: A, buf: T) -> Write<A, T>
|
|
|
|
where
|
2019-09-10 00:59:40 -04:00
|
|
|
A: DenoAsyncWrite,
|
2018-10-19 16:10:25 -04:00
|
|
|
T: AsRef<[u8]>,
|
|
|
|
{
|
|
|
|
Write {
|
2018-11-04 09:04:24 -05:00
|
|
|
state: State::Pending { a, buf },
|
2018-10-19 16:10:25 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-10 00:59:40 -04:00
|
|
|
/// This is almost the same implementation as in tokio, difference is
|
|
|
|
/// that error type is `ErrBox` instead of `std::io::Error`.
|
2018-10-19 16:10:25 -04:00
|
|
|
impl<A, T> Future for Write<A, T>
|
|
|
|
where
|
2019-09-10 00:59:40 -04:00
|
|
|
A: DenoAsyncWrite,
|
2018-10-19 16:10:25 -04:00
|
|
|
T: AsRef<[u8]>,
|
|
|
|
{
|
|
|
|
type Item = (A, T, usize);
|
2019-09-10 00:59:40 -04:00
|
|
|
type Error = ErrBox;
|
2018-10-19 16:10:25 -04:00
|
|
|
|
2019-09-10 00:59:40 -04:00
|
|
|
fn poll(&mut self) -> Poll<(A, T, usize), ErrBox> {
|
2018-10-19 16:10:25 -04:00
|
|
|
let nwritten = match self.state {
|
|
|
|
State::Pending {
|
|
|
|
ref mut a,
|
|
|
|
ref mut buf,
|
|
|
|
} => try_ready!(a.poll_write(buf.as_ref())),
|
|
|
|
State::Empty => panic!("poll a Read after it's done"),
|
|
|
|
};
|
|
|
|
|
|
|
|
match mem::replace(&mut self.state, State::Empty) {
|
|
|
|
State::Pending { a, buf } => Ok((a, buf, nwritten).into()),
|
|
|
|
State::Empty => panic!("invalid internal state"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|