cosmic_files/operation/
reader.rs

1use std::path::Path;
2use std::{fs, io};
3
4use crate::operation::OperationError;
5
6use super::Controller;
7
8// Special reader just for operations, handling cancel and progress
9pub struct OpReader {
10    file: fs::File,
11    metadata: fs::Metadata,
12    current: u64,
13    controller: Controller,
14}
15
16impl OpReader {
17    pub fn new<P: AsRef<Path>>(path: P, controller: Controller) -> io::Result<Self> {
18        let file = fs::File::open(&path)?;
19        let metadata = file.metadata()?;
20        Ok(Self {
21            file,
22            metadata,
23            current: 0,
24            controller,
25        })
26    }
27}
28
29impl io::Read for OpReader {
30    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
31        cosmic::iced::futures::executor::block_on(async {
32            self.controller
33                .check()
34                .await
35                .map_err(|s| io::Error::other(OperationError::from_state(s, &self.controller)))
36        })?;
37
38        let count = self.file.read(buf)?;
39        self.current += count as u64;
40
41        let progress = self.current as f32 / self.metadata.len() as f32;
42        self.controller.set_progress(progress);
43
44        Ok(count)
45    }
46}