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}