Revision control

Copy as Markdown

Other Tools

#![cfg(not(loom))]
//! Asynchronous file and standard stream adaptation.
//!
//! This module contains utility methods and adapter types for input/output to
//! files or standard streams (`Stdin`, `Stdout`, `Stderr`), and
//! filesystem manipulation, for use within (and only within) a Tokio runtime.
//!
//! Tasks run by *worker* threads should not block, as this could delay
//! servicing reactor events. Portable filesystem operations are blocking,
//! however. This module offers adapters which use a `blocking` annotation
//! to inform the runtime that a blocking operation is required. When
//! necessary, this allows the runtime to convert the current thread from a
//! *worker* to a *backup* thread, where blocking is acceptable.
//!
//! ## Usage
//!
//! Where possible, users should prefer the provided asynchronous-specific
//! traits such as [`AsyncRead`], or methods returning a `Future` or `Poll`
//! type. Adaptions also extend to traits like `std::io::Read` where methods
//! return `std::io::Result`. Be warned that these adapted methods may return
//! `std::io::ErrorKind::WouldBlock` if a *worker* thread can not be converted
//! to a *backup* thread immediately.
//!
//! **Warning**: These adapters may create a large number of temporary tasks,
//! especially when reading large files. When performing a lot of operations
//! in one batch, it may be significantly faster to use [`spawn_blocking`]
//! directly:
//!
//! ```
//! use tokio::fs::File;
//! use std::io::{BufReader, BufRead};
//! async fn count_lines(file: File) -> Result<usize, std::io::Error> {
//! let file = file.into_std().await;
//! tokio::task::spawn_blocking(move || {
//! let line_count = BufReader::new(file).lines().count();
//! Ok(line_count)
//! }).await?
//! }
//! ```
//!
//! [`spawn_blocking`]: fn@crate::task::spawn_blocking
//! [`AsyncRead`]: trait@crate::io::AsyncRead
mod canonicalize;
pub use self::canonicalize::canonicalize;
mod create_dir;
pub use self::create_dir::create_dir;
mod create_dir_all;
pub use self::create_dir_all::create_dir_all;
mod dir_builder;
pub use self::dir_builder::DirBuilder;
mod file;
pub use self::file::File;
mod hard_link;
pub use self::hard_link::hard_link;
mod metadata;
pub use self::metadata::metadata;
mod open_options;
pub use self::open_options::OpenOptions;
mod read;
pub use self::read::read;
mod read_dir;
pub use self::read_dir::{read_dir, DirEntry, ReadDir};
mod read_link;
pub use self::read_link::read_link;
mod read_to_string;
pub use self::read_to_string::read_to_string;
mod remove_dir;
pub use self::remove_dir::remove_dir;
mod remove_dir_all;
pub use self::remove_dir_all::remove_dir_all;
mod remove_file;
pub use self::remove_file::remove_file;
mod rename;
pub use self::rename::rename;
mod set_permissions;
pub use self::set_permissions::set_permissions;
mod symlink_metadata;
pub use self::symlink_metadata::symlink_metadata;
mod write;
pub use self::write::write;
mod copy;
pub use self::copy::copy;
mod try_exists;
pub use self::try_exists::try_exists;
#[cfg(test)]
mod mocks;
feature! {
#![unix]
mod symlink;
pub use self::symlink::symlink;
}
cfg_windows! {
mod symlink_dir;
pub use self::symlink_dir::symlink_dir;
mod symlink_file;
pub use self::symlink_file::symlink_file;
}
use std::io;
#[cfg(not(test))]
use crate::blocking::spawn_blocking;
#[cfg(test)]
use mocks::spawn_blocking;
pub(crate) async fn asyncify<F, T>(f: F) -> io::Result<T>
where
F: FnOnce() -> io::Result<T> + Send + 'static,
T: Send + 'static,
{
match spawn_blocking(f).await {
Ok(res) => res,
Err(_) => Err(io::Error::new(
io::ErrorKind::Other,
"background task failed",
)),
}
}