io_fs/coroutines/
create-file.rs

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