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
//! Rivulet is a library for creating asynchronous pipelines of contiguous data.
//!
//! Main features, at a glance:
//!
//! * **Asynchronous**: Pipeline components are `async`-aware, allowing more control over task priority and data backpressure.
//! * **Contiguous views**: Data is always contiguous, accessible by a single slice.
//! * **Modular**: Pipelines can be combined and reused using common interfaces.
//!
//! # Getting started
//!
//! The most basic interface is a [`View`].
//! Streams of data in `rivulet` are like slices, but you can't access the entire slice at once.
//! A [`View`] is sliding window over the stream, requiring only a small portion of the stream to
//! be in memory.
//!
//! A [`SplittableView`] is a special view that can split into multiple, simultaneously available views for use with multiple readers and writers.
//!
//! This crate provides a few stream implementations, but the most notable is the [`mod@circular_buffer`], which is optimized for asynchronous contiguous data access.
//!
//! # Example
//!
//! Let's create a simple averaging downsampler pipeline.
//!
//! ```
//! use rivulet::{View, ViewMut};
//! use futures::future::TryFutureExt;
//!
//! /// This function reads samples from the source, averages them,
//! /// and writes the average to the sink.
//! async fn downsample(
//! mut source: impl View<Item=f32>,
//! mut sink: impl ViewMut<Item=f32>,
//! factor: usize
//! ) -> Result<(), &'static str> {
//! loop {
//! // Wait for the input and output to be available.
//! tokio::try_join!(
//! source.grant(factor).map_err(|_| "we got an input error!"),
//! sink.grant(1).map_err(|_| "we got an output error!"),
//! )?;
//!
//! // Each view could be longer (if extra data is available)
//! // or shorter (if the stream closed)
//! let input = source.view();
//! let output = sink.view_mut();
//! if input.len() < factor || output.is_empty() {
//! break Ok(())
//! }
//!
//! // Average the values
//! output[0] = input[..factor].iter().sum::<f32>() / factor as f32;
//!
//! // We've written all our data, so release our current views
//! // and advance the streams
//! source.release(factor);
//! sink.release(1);
//! }
//! }
//! ```
pub use circular_buffer;
pub use SplittableView;
pub use ;