compio_io/lib.rs
1//! Traits and utilities for completion-based IO.
2//!
3//! # Contents
4//! ### Fundamental
5//!
6//! - [`AsyncRead`]: Async read into a buffer implements [`IoBufMut`]
7//! - [`AsyncReadAt`]: Async read into a buffer implements [`IoBufMut`] with
8//! offset
9//! - [`AsyncWrite`]: Async write from a buffer implements [`IoBuf`]
10//! - [`AsyncWriteAt`]: Async write from a buffer implements [`IoBuf`] with
11//! offset
12//!
13//! ### Buffered IO
14//!
15//! - [`AsyncBufRead`]: Trait of async read with buffered content
16//! - [`BufReader`]: An async reader with internal buffer
17//! - [`BufWriter`]: An async writer with internal buffer
18//!
19//! ### Managed IO
20//!
21//! - [`AsyncReadManaged`]: Async read with a managed buffer
22//! - [`AsyncReadManagedAt`]: Async read with a managed buffer and offset
23//! - [`AsyncReadMulti`]: Async read, and returns a stream of multiple managed
24//! buffers
25//! - [`AsyncReadMultiAt`]: Async read with offset, and returns a stream of
26//! multiple managed buffers
27//!
28//! ### Extension
29//!
30//! - [`AsyncReadExt`]: Extension trait for [`AsyncRead`]
31//! - [`AsyncReadAtExt`]: Extension trait for [`AsyncReadAt`]
32//! - [`AsyncWriteExt`]: Extension trait for [`AsyncWrite`]
33//! - [`AsyncWriteAtExt`]: Extension trait for [`AsyncWriteAt`]
34//!
35//! ### Adapters
36//! - [`framed::Framed`]: Adapts [`AsyncRead`] to [`Stream`] and [`AsyncWrite`]
37//! to [`Sink`], with framed en/decoding.
38//! - [`compat::SyncStream`]: Adapts async IO to std blocking io (requires
39//! `compat` feature)
40//! - [`compat::AsyncStream`]: Adapts async IO to [`futures_util::io`] traits
41//! (requires `compat` feature), and to `tokio::io` traits (requires `tokio`
42//! feature)
43//!
44//! [`IoBufMut`]: compio_buf::IoBufMut
45//! [`IoBuf`]: compio_buf::IoBuf
46//! [`Sink`]: futures_util::Sink
47//! [`Stream`]: futures_util::Stream
48//!
49//! # Examples
50//!
51//! ### Read
52//!
53//! ```
54//! use compio_buf::BufResult;
55//! use compio_io::AsyncRead;
56//! # futures_executor::block_on(async {
57//!
58//! let mut reader = "Hello, world!".as_bytes();
59//! let (res, buf) = reader.read(Vec::with_capacity(20)).await.unwrap();
60//!
61//! assert_eq!(buf.as_slice(), b"Hello, world!");
62//! assert_eq!(res, 13);
63//! # })
64//! ```
65//!
66//! ### Write
67//!
68//! Writing to a fixed-size buffer wrapped by [`Cursor`](std::io::Cursor). The
69//! implementation will write the content start at the current
70//! [`position`](std::io::Cursor::position):
71//!
72//! ```
73//! use std::io::Cursor;
74//!
75//! use compio_buf::BufResult;
76//! use compio_io::AsyncWrite;
77//! # futures_executor::block_on(async {
78//!
79//! let mut writer = Cursor::new([0; 6]);
80//! writer.set_position(2);
81//! let (n, buf) = writer.write(vec![1, 1, 1, 1, 1, 1]).await.unwrap();
82//!
83//! assert_eq!(n, 4);
84//! assert_eq!(writer.into_inner(), [0, 0, 1, 1, 1, 1]);
85//! # })
86//! ```
87//!
88//! Writing to `Vec<u8>`, which is extendable. Notice that the implementation
89//! will append the content to the end:
90//!
91//! ```
92//! use compio_buf::BufResult;
93//! use compio_io::AsyncWrite;
94//! # futures_executor::block_on(async {
95//!
96//! let mut writer = vec![1, 2, 3];
97//! let (_, buf) = writer.write(vec![3, 2, 1]).await.unwrap();
98//!
99//! assert_eq!(writer, [1, 2, 3, 3, 2, 1]);
100//! # })
101//! ```
102//!
103//! This crate doesn't depend on a specific runtime. It can work with `tokio`
104//! well:
105//! ```
106//! use compio_buf::BufResult;
107//! use compio_io::AsyncWrite;
108//!
109//! #[tokio::main(flavor = "current_thread")]
110//! async fn main() {
111//! let mut writer = vec![1, 2, 3];
112//! let (_, buf) = writer.write(vec![3, 2, 1]).await.unwrap();
113//!
114//! assert_eq!(writer, [1, 2, 3, 3, 2, 1]);
115//! }
116//! ```
117
118#![allow(unused_features)]
119#![warn(missing_docs)]
120#![deny(rustdoc::broken_intra_doc_links)]
121#![doc(
122 html_logo_url = "https://github.com/compio-rs/compio-logo/raw/refs/heads/master/generated/colored-bold.svg"
123)]
124#![doc(
125 html_favicon_url = "https://github.com/compio-rs/compio-logo/raw/refs/heads/master/generated/colored-bold.svg"
126)]
127// This is OK as we're thread-per-core and don't need `Send` or other auto trait on anonymous future
128#![allow(async_fn_in_trait)]
129#![cfg_attr(feature = "allocator_api", feature(allocator_api))]
130#![cfg_attr(feature = "read_buf", feature(read_buf, core_io_borrowed_buf))]
131#![cfg_attr(docsrs, feature(doc_cfg))]
132#![allow(stable_features)]
133
134use std::{future::Future, pin::Pin};
135
136#[cfg(feature = "sync")]
137use synchrony::sync;
138#[cfg(not(feature = "sync"))]
139use synchrony::unsync as sync;
140
141type PinBoxFuture<T> = Pin<Box<dyn Future<Output = T>>>;
142
143#[cfg(feature = "ancillary")]
144pub mod ancillary;
145mod buffer;
146pub mod framed;
147
148#[cfg(feature = "compat")]
149pub mod compat;
150mod read;
151pub mod util;
152mod write;
153
154pub(crate) type IoResult<T> = std::io::Result<T>;
155
156pub use read::*;
157#[doc(inline)]
158pub use util::{copy, null, repeat, split::split};
159pub use write::*;