1use futures::{Async, Future, Poll};
2use std::{io, mem, path::Path};
3use tokio_io;
4use {file, File};
5
6pub fn read<P>(path: P) -> ReadFile<P>
28where
29 P: AsRef<Path> + Send + 'static,
30{
31 ReadFile {
32 state: State::Open(File::open(path)),
33 }
34}
35
36#[derive(Debug)]
38pub struct ReadFile<P: AsRef<Path> + Send + 'static> {
39 state: State<P>,
40}
41
42#[derive(Debug)]
43enum State<P: AsRef<Path> + Send + 'static> {
44 Open(file::OpenFuture<P>),
45 Metadata(file::MetadataFuture),
46 Read(tokio_io::io::ReadToEnd<File>),
47}
48
49impl<P: AsRef<Path> + Send + 'static> Future for ReadFile<P> {
50 type Item = Vec<u8>;
51 type Error = io::Error;
52
53 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
54 let new_state = match &mut self.state {
55 State::Open(ref mut open_file) => {
56 let file = try_ready!(open_file.poll());
57 State::Metadata(file.metadata())
58 }
59 State::Metadata(read_metadata) => {
60 let (file, metadata) = try_ready!(read_metadata.poll());
61 let buf = Vec::with_capacity(metadata.len() as usize + 1);
62 let read = tokio_io::io::read_to_end(file, buf);
63 State::Read(read)
64 }
65 State::Read(ref mut read) => {
66 let (_, buf) = try_ready!(read.poll());
67 return Ok(Async::Ready(buf));
68 }
69 };
70
71 mem::replace(&mut self.state, new_state);
72 self.poll()
74 }
75}