tokio_fs/
write.rs

1use futures::{Async, Future, Poll};
2use std::{fmt, io, mem, path::Path};
3use tokio_io;
4use {file, File};
5
6/// Creates a future that will open a file for writing and write the entire
7/// contents of `contents` to it.
8///
9/// This is the async equivalent of `std::fs::write`.
10///
11/// # Examples
12///
13/// ```no_run
14/// # extern crate tokio;
15/// use tokio::prelude::Future;
16/// fn main() {
17///     let buffer = b"Hello world!";
18///     let task = tokio::fs::write("foo.txt", buffer).map(|data| {
19///         // `data` has now been written to foo.txt. The buffer is being
20///         // returned so it can be used for other things.
21///         println!("foo.txt now had {} bytes written to it", data.len());
22///     }).map_err(|e| {
23///         // handle errors
24///         eprintln!("IO error: {:?}", e);
25///     });
26///     tokio::run(task);
27/// }
28/// ```
29pub fn write<P, C: AsRef<[u8]>>(path: P, contents: C) -> WriteFile<P, C>
30where
31    P: AsRef<Path> + Send + 'static,
32{
33    WriteFile {
34        state: State::Create(File::create(path), Some(contents)),
35    }
36}
37
38/// A future used to open a file for writing and write the entire contents
39/// of some data to it.
40#[derive(Debug)]
41pub struct WriteFile<P: AsRef<Path> + Send + 'static, C: AsRef<[u8]>> {
42    state: State<P, C>,
43}
44
45#[derive(Debug)]
46enum State<P: AsRef<Path> + Send + 'static, C: AsRef<[u8]>> {
47    Create(file::CreateFuture<P>, Option<C>),
48    Write(tokio_io::io::WriteAll<File, C>),
49}
50
51impl<P: AsRef<Path> + Send + 'static, C: AsRef<[u8]> + fmt::Debug> Future for WriteFile<P, C> {
52    type Item = C;
53    type Error = io::Error;
54
55    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
56        let new_state = match &mut self.state {
57            State::Create(ref mut create_file, contents) => {
58                let file = try_ready!(create_file.poll());
59                let write = tokio_io::io::write_all(file, contents.take().unwrap());
60                State::Write(write)
61            }
62            State::Write(ref mut write) => {
63                let (_, contents) = try_ready!(write.poll());
64                return Ok(Async::Ready(contents));
65            }
66        };
67
68        mem::replace(&mut self.state, new_state);
69        // We just entered the Write state, need to poll it before returning.
70        self.poll()
71    }
72}