multi_readers/reader.rs
1use crate::inner::Inner;
2
3/// A structure that manages multiple readers, allowing sequential or concurrent
4/// access to a collection of inner readers.
5pub struct MultiReaders<T> {
6 pub(crate) inner: Vec<Inner<T>>,
7 pub(crate) len: u64,
8 pub(crate) pos: usize,
9 #[cfg(feature = "async")]
10 pub(crate) buf: Vec<u8>,
11 #[cfg(feature = "async")]
12 pub(crate) filled: usize,
13}
14
15impl<T> MultiReaders<T> {
16 /// Creates a new `MultiReaders` instance from an iterator of values.
17 pub fn new<I: Iterator<Item = T> + 'static>(values: I) -> Self {
18 Self {
19 inner: values.map(Inner::new).collect(),
20 pos: 0,
21 len: 0,
22 #[cfg(feature = "async")]
23 buf: Vec::new(),
24 #[cfg(feature = "async")]
25 filled: 0,
26 }
27 }
28}
29
30impl<T: IntoIterator<Item = E>, E> MultiReaders<T> {
31 /// Creates a new `MultiReaders` instance by flattening the nested structure of the current instance.
32 ///
33 /// This method transforms the nested structure of the `MultiReaders` into a single-level structure
34 /// by applying a `flat_map` operation on the inner elements.
35 ///
36 /// # Panics
37 ///
38 /// This method will panic if it is called after the first read operation.
39 /// It is intended to be used only during the initialization phase of the `MultiReaders`.
40 ///
41 /// # Examples
42 ///
43 /// ```rust
44 ///
45 /// use std::io::{Cursor, Read};
46 /// use multi_readers::{open, MultiReaders};
47 ///
48 /// let hello = "hello";
49 /// let world = "world";
50 /// let none = "none";
51 /// let my_open = |s: &'static str | {
52 /// if s == "none" {
53 /// None
54 /// } else {
55 /// Some(Cursor::new(s))
56 /// }
57 /// };
58 /// let readers: MultiReaders<Option<Cursor<&str>>> = open!(my_open, [hello, none, world]);
59 /// let mut readers: MultiReaders<Cursor<&str>> = readers.flatten();
60 /// let mut buf = String::new();
61 /// readers.read_to_string(&mut buf).unwrap();
62 /// assert_eq!(&buf, "helloworld");
63 /// ```
64 pub fn flatten(self) -> MultiReaders<E> {
65 if self.pos != 0 {
66 panic!("Only allowed to be called during initialization!")
67 }
68 let inner = self
69 .inner
70 .into_iter()
71 .flat_map(Inner::inner)
72 .map(Inner::new)
73 .collect();
74 MultiReaders {
75 inner,
76 pos: 0,
77 len: 0,
78 #[cfg(feature = "async")]
79 buf: Vec::new(),
80 #[cfg(feature = "async")]
81 filled: 0,
82 }
83 }
84}