io_fs/coroutines/
read-files.rs

1//! I/O-free coroutine to read multiple filesystem files contents.
2
3use std::{
4    collections::{HashMap, HashSet},
5    path::PathBuf,
6};
7
8use log::{debug, trace};
9
10use crate::{
11    error::{FsError, FsResult},
12    io::FsIo,
13};
14
15/// I/O-free coroutine to read multiple filesystem files contents.
16#[derive(Debug)]
17pub struct ReadFiles {
18    paths: Option<HashSet<PathBuf>>,
19}
20
21impl ReadFiles {
22    /// Creates a new coroutine from the given file paths.
23    pub fn new(paths: impl IntoIterator<Item = impl Into<PathBuf>>) -> Self {
24        let paths = Some(paths.into_iter().map(Into::into).collect());
25        Self { paths }
26    }
27
28    /// Makes the coroutine progress.
29    pub fn resume(&mut self, arg: Option<FsIo>) -> FsResult<HashMap<PathBuf, Vec<u8>>> {
30        let Some(arg) = arg else {
31            let Some(path) = self.paths.take() else {
32                return FsResult::Err(FsError::MissingInput);
33            };
34
35            trace!("wants I/O to read files");
36            return FsResult::Io(FsIo::ReadFiles(Err(path)));
37        };
38
39        debug!("resume after reading files");
40
41        let FsIo::ReadFiles(io) = arg else {
42            let err = FsError::InvalidArgument("read files output", arg);
43            return FsResult::Err(err);
44        };
45
46        match io {
47            Ok(contents) => FsResult::Ok(contents),
48            Err(path) => FsResult::Io(FsIo::ReadFiles(Err(path))),
49        }
50    }
51}