1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//! Fixed-length, allocation and lock-free, async I/O oriented single-producer single-consumer
//! (SPSC) queues.
//!
//! # Overview
//! This library provides several fixed-length queues for different use-cases, based around the same
//! core:
//! - [`asyncio`] is a generic async, thread-safe, lock-free queue using [futures]. Read
//! operations can pause until data is available, and write operations can pause until space is
//! returned. The queue can act as an efficient I/O buffer with [`futures::AsyncRead`] and
//! [`futures::AsyncWrite`] implementations.
//! - [`blocking`] is a generic thread-safe queue. Read operations can block until data is
//! available, and write operations can block until space is returned. The queue can act as an
//! efficient I/O buffer with [`io::Read`] and [`io::Write`] implementations.
//! - [`nonblocking`] is a generic thread-safe, lock-free queue that is guaranteed to not block.
//! It can act as an efficient I/O buffer when read and write speed is matched or no locks
//! are available.
//!
//! All queues have separate `Reader` and `Writer` ends which can be sent across threads. Queues are
//! designed with bulk operations in mind, so can safely be used with large read and write
//! operations, such as in a byte array I/O context.
//!
//! The library also provides [`Ring`], a low-level atomic ring buffer building block used to
//! implement the various queues available.
//!
//! The library supports `no_std` with a reduced feature set, and is highly configurable. With the
//! default feature set, it does not require any dependencies.
//!
//! # Features
//!
//! - `asyncio` - enables the [`asyncio`] queue, using the [`futures`] library. Requires [`alloc`].
//! - `blocking` - enables the [`blocking`] queue. Requires [`std`] (as this queue uses locks).
//! - `nonblocking` - enables the [`nonblocking`] queue. Requires [`alloc`].
//! - `heap-buffer` - enables [`HeapBuffer`], which allocates queue storage on the heap. Requires [`alloc`].
//! - `stack-buffer` - enables [`StackBuffer`], which allocates queue storage on the stack.
//! - `std-io` - enables implementations for standard I/O traits ([`io::Read`], [`io::Write`], and
//! [`futures::AsyncRead`] and [`futures::AsyncWrite`]). Requires [`std`].
//!
//! # Examples
//! ## Simple async example
//! ```
//! use futures::executor::block_on;
//! use futures::join;
//! use mini_io_queue::asyncio::queue;
//!
//! let (mut reader, mut writer) = queue(8);
//!
//! let write_loop = async {
//! for i in 0..16 {
//! writer.write_all(&[i]).await.unwrap();
//! }
//! };
//!
//! let read_loop = async {
//! for i in 0..16 {
//! let mut buf = [0];
//! reader.read_exact(&mut buf).await.unwrap();
//!
//! assert_eq!(buf[0], i);
//! }
//! };
//!
//! block_on(async { join!(write_loop, read_loop) });
//! ```
//!
//! ## Blocking queue with a custom ring
//! ```
//! use mini_io_queue::blocking::queue_from_parts;
//! use mini_io_queue::Ring;
//! use mini_io_queue::storage::{HeapBuffer, Storage};
//!
//! // Create a queue with half of the underlying buffer in the read side.
//! let ring = Ring::new(10);
//! ring.advance_right(5);
//!
//! let mut buffer = HeapBuffer::new(10);
//! buffer.slice_mut(0..5).copy_from_slice(&[1, 2, 3, 4, 5]);
//!
//! let (mut reader, _) = queue_from_parts(ring, buffer);
//!
//! for i in 1..=5 {
//! let mut buf = [0];
//! reader.read_exact(&mut buf).unwrap();
//!
//! assert_eq!(buf[0], i);
//! }
//! ```
//!
//! [`io::Read`]: std::io::Read
//! [`io::Write`]: std::io::Write
//! [`HeapBuffer`]: storage::HeapBuffer
//! [`StackBuffer`]: storage::StackBuffer
extern crate core;
extern crate alloc;
pub use *;
pub use *;