Skip to main content

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)
42//!
43//! [`IoBufMut`]: compio_buf::IoBufMut
44//! [`IoBuf`]: compio_buf::IoBuf
45//! [`Sink`]: futures_util::Sink
46//! [`Stream`]: futures_util::Stream
47//!
48//! # Examples
49//!
50//! ### Read
51//!
52//! ```
53//! use compio_buf::BufResult;
54//! use compio_io::AsyncRead;
55//! # futures_executor::block_on(async {
56//!
57//! let mut reader = "Hello, world!".as_bytes();
58//! let (res, buf) = reader.read(Vec::with_capacity(20)).await.unwrap();
59//!
60//! assert_eq!(buf.as_slice(), b"Hello, world!");
61//! assert_eq!(res, 13);
62//! # })
63//! ```
64//!
65//! ### Write
66//!
67//! Writing to a fixed-size buffer wrapped by [`Cursor`](std::io::Cursor). The
68//! implementation will write the content start at the current
69//! [`position`](std::io::Cursor::position):
70//!
71//! ```
72//! use std::io::Cursor;
73//!
74//! use compio_buf::BufResult;
75//! use compio_io::AsyncWrite;
76//! # futures_executor::block_on(async {
77//!
78//! let mut writer = Cursor::new([0; 6]);
79//! writer.set_position(2);
80//! let (n, buf) = writer.write(vec![1, 1, 1, 1, 1, 1]).await.unwrap();
81//!
82//! assert_eq!(n, 4);
83//! assert_eq!(writer.into_inner(), [0, 0, 1, 1, 1, 1]);
84//! # })
85//! ```
86//!
87//! Writing to `Vec<u8>`, which is extendable. Notice that the implementation
88//! will append the content to the end:
89//!
90//! ```
91//! use compio_buf::BufResult;
92//! use compio_io::AsyncWrite;
93//! # futures_executor::block_on(async {
94//!
95//! let mut writer = vec![1, 2, 3];
96//! let (_, buf) = writer.write(vec![3, 2, 1]).await.unwrap();
97//!
98//! assert_eq!(writer, [1, 2, 3, 3, 2, 1]);
99//! # })
100//! ```
101//!
102//! This crate doesn't depend on a specific runtime. It can work with `tokio`
103//! well:
104//! ```
105//! use compio_buf::BufResult;
106//! use compio_io::AsyncWrite;
107//!
108//! #[tokio::main(flavor = "current_thread")]
109//! async fn main() {
110//!     let mut writer = vec![1, 2, 3];
111//!     let (_, buf) = writer.write(vec![3, 2, 1]).await.unwrap();
112//!
113//!     assert_eq!(writer, [1, 2, 3, 3, 2, 1]);
114//! }
115//! ```
116
117#![allow(unused_features)]
118#![warn(missing_docs)]
119#![deny(rustdoc::broken_intra_doc_links)]
120#![doc(
121    html_logo_url = "https://github.com/compio-rs/compio-logo/raw/refs/heads/master/generated/colored-bold.svg"
122)]
123#![doc(
124    html_favicon_url = "https://github.com/compio-rs/compio-logo/raw/refs/heads/master/generated/colored-bold.svg"
125)]
126// This is OK as we're thread-per-core and don't need `Send` or other auto trait on anonymous future
127#![allow(async_fn_in_trait)]
128#![cfg_attr(feature = "allocator_api", feature(allocator_api))]
129#![cfg_attr(feature = "read_buf", feature(read_buf, core_io_borrowed_buf))]
130#![cfg_attr(docsrs, feature(doc_cfg))]
131
132use std::{future::Future, pin::Pin};
133
134#[cfg(feature = "sync")]
135use synchrony::sync;
136#[cfg(not(feature = "sync"))]
137use synchrony::unsync as sync;
138
139type PinBoxFuture<T> = Pin<Box<dyn Future<Output = T>>>;
140
141#[cfg(feature = "ancillary")]
142pub mod ancillary;
143mod buffer;
144pub mod framed;
145
146#[cfg(feature = "compat")]
147pub mod compat;
148mod read;
149pub mod util;
150mod write;
151
152pub(crate) type IoResult<T> = std::io::Result<T>;
153
154pub use read::*;
155#[doc(inline)]
156pub use util::{copy, null, repeat, split::split};
157pub use write::*;