1 #![deny(missing_docs, missing_debug_implementations)]
2 #![doc(html_root_url = "https://docs.rs/tokio-fs/0.1.7")]
3 
4 //! Asynchronous file and standard stream adaptation.
5 //!
6 //! This module contains utility methods and adapter types for input/output to
7 //! files or standard streams (`Stdin`, `Stdout`, `Stderr`), and
8 //! filesystem manipulation, for use within (and only within) a Tokio runtime.
9 //!
10 //! Tasks run by *worker* threads should not block, as this could delay
11 //! servicing reactor events. Portable filesystem operations are blocking,
12 //! however. This module offers adapters which use a [`blocking`] annotation
13 //! to inform the runtime that a blocking operation is required. When
14 //! necessary, this allows the runtime to convert the current thread from a
15 //! *worker* to a *backup* thread, where blocking is acceptable.
16 //!
17 //! ## Usage
18 //!
19 //! Where possible, users should prefer the provided asynchronous-specific
20 //! traits such as [`AsyncRead`], or methods returning a `Future` or `Poll`
21 //! type. Adaptions also extend to traits like `std::io::Read` where methods
22 //! return `std::io::Result`.  Be warned that these adapted methods may return
23 //! `std::io::ErrorKind::WouldBlock` if a *worker* thread can not be converted
24 //! to a *backup* thread immediately. See [tokio-threadpool] for more details
25 //! of the threading model and [`blocking`].
26 //!
27 //! [`blocking`]: https://docs.rs/tokio-threadpool/0.1/tokio_threadpool/fn.blocking.html
28 //! [`AsyncRead`]: https://docs.rs/tokio-io/0.1/tokio_io/trait.AsyncRead.html
29 //! [tokio-threadpool]: https://docs.rs/tokio-threadpool/0.1/tokio_threadpool
30 
31 #[macro_use]
32 extern crate futures;
33 extern crate tokio_io;
34 extern crate tokio_threadpool;
35 
36 mod create_dir;
37 mod create_dir_all;
38 pub mod file;
39 mod hard_link;
40 mod metadata;
41 pub mod os;
42 mod read;
43 mod read_dir;
44 mod read_link;
45 mod remove_dir;
46 mod remove_file;
47 mod rename;
48 mod set_permissions;
49 mod stderr;
50 mod stdin;
51 mod stdout;
52 mod symlink_metadata;
53 mod write;
54 
55 pub use create_dir::{create_dir, CreateDirFuture};
56 pub use create_dir_all::{create_dir_all, CreateDirAllFuture};
57 pub use file::File;
58 pub use file::OpenOptions;
59 pub use hard_link::{hard_link, HardLinkFuture};
60 pub use metadata::{metadata, MetadataFuture};
61 pub use read::{read, ReadFile};
62 pub use read_dir::{read_dir, DirEntry, ReadDir, ReadDirFuture};
63 pub use read_link::{read_link, ReadLinkFuture};
64 pub use remove_dir::{remove_dir, RemoveDirFuture};
65 pub use remove_file::{remove_file, RemoveFileFuture};
66 pub use rename::{rename, RenameFuture};
67 pub use set_permissions::{set_permissions, SetPermissionsFuture};
68 pub use stderr::{stderr, Stderr};
69 pub use stdin::{stdin, Stdin};
70 pub use stdout::{stdout, Stdout};
71 pub use symlink_metadata::{symlink_metadata, SymlinkMetadataFuture};
72 pub use write::{write, WriteFile};
73 
74 use futures::Async::*;
75 use futures::Poll;
76 
77 use std::io;
78 use std::io::ErrorKind::{Other, WouldBlock};
79 
blocking_io<F, T>(f: F) -> Poll<T, io::Error> where F: FnOnce() -> io::Result<T>,80 fn blocking_io<F, T>(f: F) -> Poll<T, io::Error>
81 where
82     F: FnOnce() -> io::Result<T>,
83 {
84     match tokio_threadpool::blocking(f) {
85         Ok(Ready(Ok(v))) => Ok(v.into()),
86         Ok(Ready(Err(err))) => Err(err),
87         Ok(NotReady) => Ok(NotReady),
88         Err(_) => Err(blocking_err()),
89     }
90 }
91 
would_block<F, T>(f: F) -> io::Result<T> where F: FnOnce() -> io::Result<T>,92 fn would_block<F, T>(f: F) -> io::Result<T>
93 where
94     F: FnOnce() -> io::Result<T>,
95 {
96     match tokio_threadpool::blocking(f) {
97         Ok(Ready(Ok(v))) => Ok(v),
98         Ok(Ready(Err(err))) => {
99             debug_assert_ne!(err.kind(), WouldBlock);
100             Err(err)
101         }
102         Ok(NotReady) => Err(WouldBlock.into()),
103         Err(_) => Err(blocking_err()),
104     }
105 }
106 
blocking_err() -> io::Error107 fn blocking_err() -> io::Error {
108     io::Error::new(
109         Other,
110         "`blocking` annotated I/O must be called \
111          from the context of the Tokio runtime.",
112     )
113 }
114