io_fs/coroutines/
create-files.rs

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